From 3c4a64e807074d7f6ea46f42daa078769250885d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Fri, 1 Aug 2025 20:56:22 -0400 Subject: [PATCH] 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 Part-of: --- src/compiler/nir/nir.c | 82 ++++++++++++++++++++++++++++++++++++++---- src/compiler/nir/nir.h | 9 +++++ 2 files changed, 84 insertions(+), 7 deletions(-) diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c index ebf56534364..f92f9c57704 100644 --- a/src/compiler/nir/nir.c +++ b/src/compiler/nir/nir.c @@ -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; } diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 04265d6610f..d42c78385fd 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -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