From ff71fae4403269c6ecd99cf15fa03a7a54355626 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Mon, 4 Nov 2019 18:09:26 -0500 Subject: [PATCH] nir: strip as we serialize to remove the nir_shader_clone call Serializing stripped NIR is faster now. Reviewed-by: Connor Abbott --- src/compiler/Makefile.sources | 1 - src/compiler/nir/meson.build | 1 - src/compiler/nir/nir.h | 2 - src/compiler/nir/nir_serialize.c | 60 ++++++++++-------- src/compiler/nir/nir_strip.c | 104 ------------------------------- 5 files changed, 34 insertions(+), 134 deletions(-) delete mode 100644 src/compiler/nir/nir_strip.c diff --git a/src/compiler/Makefile.sources b/src/compiler/Makefile.sources index 7b593059834..0ca94d41d29 100644 --- a/src/compiler/Makefile.sources +++ b/src/compiler/Makefile.sources @@ -331,7 +331,6 @@ NIR_FILES = \ nir/nir_search_helpers.h \ nir/nir_serialize.c \ nir/nir_serialize.h \ - nir/nir_strip.c \ nir/nir_split_per_member_structs.c \ nir/nir_split_var_copies.c \ nir/nir_split_vars.c \ diff --git a/src/compiler/nir/meson.build b/src/compiler/nir/meson.build index b114623d3b3..0a5440c806b 100644 --- a/src/compiler/nir/meson.build +++ b/src/compiler/nir/meson.build @@ -213,7 +213,6 @@ files_libnir = files( 'nir_search_helpers.h', 'nir_serialize.c', 'nir_serialize.h', - 'nir_strip.c', 'nir_split_per_member_structs.c', 'nir_split_var_copies.c', 'nir_split_vars.c', diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index bae8c821243..1333a49c66f 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -4192,8 +4192,6 @@ bool nir_opt_vectorize(nir_shader *shader); bool nir_opt_conditional_discard(nir_shader *shader); -void nir_strip(nir_shader *shader); - void nir_sweep(nir_shader *shader); void nir_remap_dual_slot_attributes(nir_shader *shader, diff --git a/src/compiler/nir/nir_serialize.c b/src/compiler/nir/nir_serialize.c index 18398545220..b8422209e7d 100644 --- a/src/compiler/nir/nir_serialize.c +++ b/src/compiler/nir/nir_serialize.c @@ -49,6 +49,9 @@ typedef struct { * be resolved in the second pass. */ struct util_dynarray phi_fixups; + + /* Don't write optional data such as variable names. */ + bool strip; } write_ctx; typedef struct { @@ -159,7 +162,7 @@ write_variable(write_ctx *ctx, const nir_variable *var) union packed_var flags; flags.u32 = 0; - flags.u.has_name = !!(var->name); + flags.u.has_name = !ctx->strip && var->name; flags.u.has_constant_initializer = !!(var->constant_initializer); flags.u.has_interface_type = !!(var->interface_type); flags.u.num_state_slots = var->num_state_slots; @@ -167,9 +170,21 @@ write_variable(write_ctx *ctx, const nir_variable *var) blob_write_uint32(ctx->blob, flags.u32); - if (var->name) + if (flags.u.has_name) blob_write_string(ctx->blob, var->name); - blob_write_bytes(ctx->blob, (uint8_t *) &var->data, sizeof(var->data)); + + struct nir_variable_data data = var->data; + + /* When stripping, we expect that the location is no longer needed, + * which is typically after shaders are linked. + */ + if (ctx->strip && + data.mode != nir_var_shader_in && + data.mode != nir_var_shader_out) + data.location = 0; + + blob_write_bytes(ctx->blob, &data, sizeof(data)); + for (unsigned i = 0; i < var->num_state_slots; i++) { blob_write_bytes(ctx->blob, &var->state_slots[i], sizeof(var->state_slots[i])); @@ -258,8 +273,8 @@ write_register(write_ctx *ctx, const nir_register *reg) blob_write_uint32(ctx->blob, reg->bit_size); blob_write_uint32(ctx->blob, reg->num_array_elems); blob_write_uint32(ctx->blob, reg->index); - blob_write_uint32(ctx->blob, !!(reg->name)); - if (reg->name) + blob_write_uint32(ctx->blob, !ctx->strip && reg->name); + if (!ctx->strip && reg->name) blob_write_string(ctx->blob, reg->name); } @@ -357,7 +372,7 @@ write_dest(write_ctx *ctx, const nir_dest *dst) { uint32_t val = dst->is_ssa; if (dst->is_ssa) { - val |= !!(dst->ssa.name) << 1; + val |= (!ctx->strip && dst->ssa.name) << 1; val |= dst->ssa.num_components << 2; val |= dst->ssa.bit_size << 5; } else { @@ -366,7 +381,7 @@ write_dest(write_ctx *ctx, const nir_dest *dst) blob_write_uint32(ctx->blob, val); if (dst->is_ssa) { write_add_object(ctx, &dst->ssa); - if (dst->ssa.name) + if (!ctx->strip && dst->ssa.name) blob_write_string(ctx->blob, dst->ssa.name); } else { blob_write_uint32(ctx->blob, write_lookup_object(ctx, dst->reg.reg)); @@ -1120,40 +1135,36 @@ read_function(read_ctx *ctx) fxn->impl = NIR_SERIALIZE_FUNC_HAS_IMPL; } +/** + * Serialize NIR into a binary blob. + * + * \param strip Don't serialize information only useful for debugging, + * such as variable names, making cache hits from similar + * shaders more likely. + */ void nir_serialize(struct blob *blob, const nir_shader *nir, bool strip) { - nir_shader *stripped = NULL; - - if (strip) { - /* Drop unnecessary information (like variable names), so the serialized - * NIR is smaller, and also to let us detect more isomorphic shaders - * when hashing, increasing cache hits. - */ - stripped = nir_shader_clone(NULL, nir); - nir_strip(stripped); - nir = stripped; - } - write_ctx ctx; ctx.remap_table = _mesa_pointer_hash_table_create(NULL); ctx.next_idx = 0; ctx.blob = blob; ctx.nir = nir; + ctx.strip = strip; util_dynarray_init(&ctx.phi_fixups, NULL); size_t idx_size_offset = blob_reserve_uint32(blob); struct shader_info info = nir->info; uint32_t strings = 0; - if (info.name) + if (!strip && info.name) strings |= 0x1; - if (info.label) + if (!strip && info.label) strings |= 0x2; blob_write_uint32(blob, strings); - if (info.name) + if (!strip && info.name) blob_write_string(blob, info.name); - if (info.label) + if (!strip && info.label) blob_write_string(blob, info.label); info.name = info.label = NULL; blob_write_bytes(blob, (uint8_t *) &info, sizeof(info)); @@ -1189,9 +1200,6 @@ nir_serialize(struct blob *blob, const nir_shader *nir, bool strip) _mesa_hash_table_destroy(ctx.remap_table, NULL); util_dynarray_fini(&ctx.phi_fixups); - - if (strip) - ralloc_free(stripped); } nir_shader * diff --git a/src/compiler/nir/nir_strip.c b/src/compiler/nir/nir_strip.c deleted file mode 100644 index ba7465c37d1..00000000000 --- a/src/compiler/nir/nir_strip.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright © 2019 Valve Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - */ - -#include "nir.h" -#include "util/debug.h" - -/* This pass removes information which is only useful for debugging, - * making cache hits from similar shaders more likely. - */ - -static void -strip_variable(nir_variable *var) -{ - var->name = NULL; - - if (var->data.mode != nir_var_shader_in && - var->data.mode != nir_var_shader_out) { - /* We assume that this is called after nir_lower_io(), at which point - * the original user-facing location is irrelevant except for inputs and - * outputs. - */ - var->data.location = 0; - } -} - -static void -strip_register(nir_register *reg) -{ - reg->name = NULL; -} - -static bool -strip_def(nir_ssa_def *def, void *_unused) -{ - (void) _unused; - def->name = NULL; - return true; -} - -static void -strip_impl(nir_function_impl *impl) -{ - nir_index_ssa_defs(impl); - - nir_foreach_variable(var, &impl->locals) - strip_variable(var); - nir_foreach_register(reg, &impl->registers) - strip_register(reg); - nir_foreach_block(block, impl) { - nir_foreach_instr(instr, block) { - nir_foreach_ssa_def(instr, strip_def, NULL); - } - } -} - -void -nir_strip(nir_shader *shader) -{ - static int should_strip = -1; - if (should_strip < 0) - should_strip = env_var_as_boolean("NIR_STRIP", true); - if (!should_strip) - return; - - shader->info.name = NULL; - shader->info.label = NULL; - - nir_foreach_variable(var, &shader->uniforms) - strip_variable(var); - nir_foreach_variable(var, &shader->inputs) - strip_variable(var); - nir_foreach_variable(var, &shader->outputs) - strip_variable(var); - nir_foreach_variable(var, &shader->system_values) - strip_variable(var); - nir_foreach_variable(var, &shader->globals) - strip_variable(var); - - nir_foreach_function(func, shader) { - if (func->impl) - strip_impl(func->impl); - } -} -- 2.30.2