summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Olšák <marek.olsak@amd.com>2019-11-04 18:09:26 -0500
committerMarek Olšák <marek.olsak@amd.com>2019-11-21 18:49:57 -0500
commitff71fae4403269c6ecd99cf15fa03a7a54355626 (patch)
treedcf52e4abcaa0863d4acc911261cad29100950fe
parent8acaab1aa76baed96516d5eb33144df6311ee78d (diff)
nir: strip as we serialize to remove the nir_shader_clone call
Serializing stripped NIR is faster now. Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
-rw-r--r--src/compiler/Makefile.sources1
-rw-r--r--src/compiler/nir/meson.build1
-rw-r--r--src/compiler/nir/nir.h2
-rw-r--r--src/compiler/nir/nir_serialize.c60
-rw-r--r--src/compiler/nir/nir_strip.c104
5 files changed, 34 insertions, 134 deletions
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);
- }
-}