summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/nir/nir.h2
-rw-r--r--src/compiler/nir/nir_validate.c96
2 files changed, 98 insertions, 0 deletions
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index bb3507ff862..21cc4a71053 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -3886,6 +3886,7 @@ void nir_shader_serialize_deserialize(nir_shader *s);
#ifndef NDEBUG
void nir_validate_shader(nir_shader *shader, const char *when);
+void nir_validate_ssa_dominance(nir_shader *shader, const char *when);
void nir_metadata_set_validation_flag(nir_shader *shader);
void nir_metadata_check_validation_flag(nir_shader *shader);
@@ -3937,6 +3938,7 @@ should_print_nir(void)
}
#else
static inline void nir_validate_shader(nir_shader *shader, const char *when) { (void) shader; (void)when; }
+static inline void nir_validate_ssa_dominance(nir_shader *shader, const char *when) { (void) shader; (void)when; }
static inline void nir_metadata_set_validation_flag(nir_shader *shader) { (void) shader; }
static inline void nir_metadata_check_validation_flag(nir_shader *shader) { (void) shader; }
static inline bool should_skip_nir(UNUSED const char *pass_name) { return false; }
diff --git a/src/compiler/nir/nir_validate.c b/src/compiler/nir/nir_validate.c
index 1a9732365d6..90576b0a08f 100644
--- a/src/compiler/nir/nir_validate.c
+++ b/src/compiler/nir/nir_validate.c
@@ -1206,6 +1206,60 @@ validate_var_decl(nir_variable *var, nir_variable_mode valid_modes,
state->var = NULL;
}
+static bool
+validate_ssa_def_dominance(nir_ssa_def *def, void *_state)
+{
+ validate_state *state = _state;
+
+ validate_assert(state, def->index < state->impl->ssa_alloc);
+ validate_assert(state, !BITSET_TEST(state->ssa_defs_found, def->index));
+ BITSET_SET(state->ssa_defs_found, def->index);
+
+ return true;
+}
+
+static bool
+validate_src_dominance(nir_src *src, void *_state)
+{
+ validate_state *state = _state;
+ if (!src->is_ssa)
+ return true;
+
+ if (src->ssa->parent_instr->block == src->parent_instr->block) {
+ validate_assert(state, src->ssa->index < state->impl->ssa_alloc);
+ validate_assert(state, BITSET_TEST(state->ssa_defs_found,
+ src->ssa->index));
+ } else {
+ validate_assert(state, nir_block_dominates(src->ssa->parent_instr->block,
+ src->parent_instr->block));
+ }
+ return true;
+}
+
+static void
+validate_ssa_dominance(nir_function_impl *impl, validate_state *state)
+{
+ nir_metadata_require(impl, nir_metadata_dominance);
+
+ nir_foreach_block(block, impl) {
+ state->block = block;
+ nir_foreach_instr(instr, block) {
+ state->instr = instr;
+ if (instr->type == nir_instr_type_phi) {
+ nir_phi_instr *phi = nir_instr_as_phi(instr);
+ nir_foreach_phi_src(src, phi) {
+ validate_assert(state,
+ nir_block_dominates(src->src.ssa->parent_instr->block,
+ src->pred));
+ }
+ } else {
+ nir_foreach_src(instr, validate_src_dominance, state);
+ }
+ nir_foreach_ssa_def(instr, validate_ssa_def_dominance, state);
+ }
+ }
+}
+
static void
validate_function_impl(nir_function_impl *impl, validate_state *state)
{
@@ -1257,6 +1311,14 @@ validate_function_impl(nir_function_impl *impl, validate_state *state)
validate_assert(state, state->ssa_srcs->entries == 0);
_mesa_set_clear(state->ssa_srcs, NULL);
+
+ static int validate_dominance = -1;
+ if (validate_dominance < 0) {
+ validate_dominance =
+ env_var_as_boolean("NIR_VALIDATE_SSA_DOMINANCE", false);
+ }
+ if (validate_dominance)
+ validate_ssa_dominance(impl, state);
}
static void
@@ -1365,4 +1427,38 @@ nir_validate_shader(nir_shader *shader, const char *when)
destroy_validate_state(&state);
}
+void
+nir_validate_ssa_dominance(nir_shader *shader, const char *when)
+{
+ static int should_validate = -1;
+ if (should_validate < 0)
+ should_validate = env_var_as_boolean("NIR_VALIDATE", true);
+ if (!should_validate)
+ return;
+
+ validate_state state;
+ init_validate_state(&state);
+
+ state.shader = shader;
+
+ nir_foreach_function(func, shader) {
+ if (func->impl == NULL)
+ continue;
+
+ state.ssa_defs_found = reralloc(state.mem_ctx, state.ssa_defs_found,
+ BITSET_WORD,
+ BITSET_WORDS(func->impl->ssa_alloc));
+ memset(state.ssa_defs_found, 0, BITSET_WORDS(func->impl->ssa_alloc) *
+ sizeof(BITSET_WORD));
+
+ state.impl = func->impl;
+ validate_ssa_dominance(func->impl, &state);
+ }
+
+ if (_mesa_hash_table_num_entries(state.errors) > 0)
+ dump_errors(&state, when);
+
+ destroy_validate_state(&state);
+}
+
#endif /* NDEBUG */