aco/optimizer: validate context data

Reviewed-by: Daniel Schürmann <daniel@schuermann.dev>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34858>
This commit is contained in:
Georg Lehmann 2024-07-30 10:45:13 +02:00 committed by Marge Bot
parent 906b7dbcec
commit c0e88c376a
4 changed files with 59 additions and 2 deletions

View file

@ -447,7 +447,7 @@ aco_get_codegen_flags()
init();
/* Exclude flags which don't affect code generation. */
uint64_t exclude = DEBUG_VALIDATE_IR | DEBUG_VALIDATE_RA | DEBUG_PERF_INFO | DEBUG_LIVE_INFO |
DEBUG_NO_VALIDATE | DEBUG_VALIDATE_LIVE_VARS;
DEBUG_NO_VALIDATE | DEBUG_VALIDATE_LIVE_VARS | DEBUG_VALIDATE_OPT;
return debug_flags & ~exclude;
}

View file

@ -22,6 +22,7 @@ static const struct debug_control aco_debug_options[] = {
{"validateir", DEBUG_VALIDATE_IR},
{"validatera", DEBUG_VALIDATE_RA},
{"validate-livevars", DEBUG_VALIDATE_LIVE_VARS},
{"validateopt", DEBUG_VALIDATE_OPT},
{"novalidate", DEBUG_NO_VALIDATE},
{"force-waitcnt", DEBUG_FORCE_WAITCNT},
{"force-waitdeps", DEBUG_FORCE_WAITDEPS},
@ -44,7 +45,7 @@ init_once()
#ifndef NDEBUG
/* enable some flags by default on debug builds */
if (!(debug_flags & aco::DEBUG_NO_VALIDATE)) {
debug_flags |= aco::DEBUG_VALIDATE_IR;
debug_flags |= aco::DEBUG_VALIDATE_IR | DEBUG_VALIDATE_OPT;
}
#endif
}

View file

@ -43,6 +43,7 @@ enum {
DEBUG_NO_VALIDATE = 0x400,
DEBUG_NO_SCHED_ILP = 0x800,
DEBUG_NO_SCHED_VOPD = 0x1000,
DEBUG_VALIDATE_OPT = 0x2000,
};
enum storage_class : uint8_t {

View file

@ -5060,6 +5060,51 @@ apply_literals(opt_ctx& ctx, aco_ptr<Instruction>& instr)
ctx.instructions.emplace_back(std::move(instr));
}
void
validate_opt_ctx(opt_ctx& ctx)
{
if (!(debug_flags & DEBUG_VALIDATE_OPT))
return;
Program* program = ctx.program;
bool is_valid = true;
auto check = [&program, &is_valid](bool success, const char* msg,
aco::Instruction* instr) -> void
{
if (!success) {
char* out;
size_t outsize;
struct u_memstream mem;
u_memstream_open(&mem, &out, &outsize);
FILE* const memf = u_memstream_get(&mem);
fprintf(memf, "Optimizer: %s: ", msg);
aco_print_instr(program->gfx_level, instr, memf);
u_memstream_close(&mem);
aco_err(program, "%s", out);
free(out);
is_valid = false;
}
};
for (Block& block : program->blocks) {
for (aco_ptr<Instruction>& instr : block.instructions) {
if (!instr)
continue;
for (const Definition& def : instr->definitions) {
check(ctx.info[def.tempId()].parent_instr == instr.get(), "parent_instr incorrect",
instr.get());
}
}
}
if (!is_valid) {
abort();
}
}
} /* end namespace */
void
@ -5076,11 +5121,15 @@ optimize(Program* program)
label_instruction(ctx, instr);
}
validate_opt_ctx(ctx);
ctx.uses = dead_code_analysis(program);
/* 2. Rematerialize constants in every block. */
rematerialize_constants(ctx);
validate_opt_ctx(ctx);
/* 3. Combine v_mad, omod, clamp and propagate sgpr on VALU instructions */
for (Block& block : program->blocks) {
ctx.fp_mode = block.fp_mode;
@ -5088,6 +5137,8 @@ optimize(Program* program)
combine_instruction(ctx, instr);
}
validate_opt_ctx(ctx);
/* 4. Top-Down DAG pass (backward) to select instructions (includes DCE) */
for (auto block_rit = program->blocks.rbegin(); block_rit != program->blocks.rend();
++block_rit) {
@ -5098,6 +5149,8 @@ optimize(Program* program)
select_instruction(ctx, *instr_rit);
}
validate_opt_ctx(ctx);
/* 5. Add literals to instructions */
for (Block& block : program->blocks) {
ctx.instructions.reserve(block.instructions.size());
@ -5106,6 +5159,8 @@ optimize(Program* program)
apply_literals(ctx, instr);
block.instructions = std::move(ctx.instructions);
}
validate_opt_ctx(ctx);
}
} // namespace aco