diff options
-rw-r--r-- | src/compiler/nir/nir.h | 2 | ||||
-rw-r--r-- | src/compiler/nir/nir_validate.c | 96 |
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 */ |