aco: rework the way various compilation/validation errors are reported

The upcoming change will allow to report all ACO errors (or warnings)
directly to the app via VK_EXT_debug_report. This is similar to what
we already do for reporting various SPIRV->NIR errors.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Rhys Perry <pendingchaos02@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6318>
This commit is contained in:
Samuel Pitoiset 2020-08-14 10:42:27 +02:00
parent bc723dfda7
commit c2b1978aa4
9 changed files with 239 additions and 322 deletions

View File

@ -80,8 +80,17 @@ void emit_instruction(asm_context& ctx, std::vector<uint32_t>& out, Instruction*
uint32_t opcode = ctx.opcode[(int)instr->opcode];
if (opcode == (uint32_t)-1) {
fprintf(stderr, "Unsupported opcode: ");
aco_print_instr(instr, stderr);
char *out;
size_t outsize;
FILE *memf = open_memstream(&out, &outsize);
fprintf(memf, "Unsupported opcode: ");
aco_print_instr(instr, memf);
fclose(memf);
aco_err(ctx.program, out);
free(out);
abort();
}
@ -737,7 +746,7 @@ void fix_exports(asm_context& ctx, std::vector<uint32_t>& out, Program* program)
if (!exported) {
/* Abort in order to avoid a GPU hang. */
fprintf(stderr, "Missing export in %s shader:\n", (program->stage & hw_vs) ? "vertex" : "fragment");
aco_err(program, "Missing export in %s shader:", (program->stage & hw_vs) ? "vertex" : "fragment");
aco_print_program(program, stderr);
abort();
}

View File

@ -38,6 +38,23 @@
namespace aco {
namespace {
#define isel_err(...) _isel_err(ctx, __FILE__, __LINE__, __VA_ARGS__)
static void _isel_err(isel_context *ctx, const char *file, unsigned line,
const nir_instr *instr, const char *msg)
{
char *out;
size_t outsize;
FILE *memf = open_memstream(&out, &outsize);
fprintf(memf, "%s: ", msg);
nir_print_instr(instr, memf);
fclose(memf);
_aco_err(ctx->program, file, line, out);
free(out);
}
class loop_info_RAII {
isel_context* ctx;
unsigned header_idx_old;
@ -951,9 +968,7 @@ void emit_bcsel(isel_context *ctx, nir_alu_instr *instr, Temp dst)
bld.pseudo(aco_opcode::p_create_vector, Definition(dst), dst0, dst1);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
return;
}
@ -971,9 +986,7 @@ void emit_bcsel(isel_context *ctx, nir_alu_instr *instr, Temp dst)
aco_opcode op = dst.regClass() == s1 ? aco_opcode::s_cselect_b32 : aco_opcode::s_cselect_b64;
bld.sop2(op, Definition(dst), then, els, bld.scc(bool_to_scalar_condition(ctx, cond)));
} else {
fprintf(stderr, "Unimplemented uniform bcsel bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented uniform bcsel bit size");
}
return;
}
@ -1128,9 +1141,7 @@ Temp emit_floor_f64(isel_context *ctx, Builder& bld, Definition dst, Temp val)
void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
{
if (!instr->dest.dest.is_ssa) {
fprintf(stderr, "nir alu dst not in ssa: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "nir alu dst not in ssa");
abort();
}
Builder bld(ctx->program, ctx->block);
@ -1224,9 +1235,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
aco_opcode opcode = dst.size() == 1 ? aco_opcode::s_not_b32 : aco_opcode::s_not_b64;
bld.sop1(opcode, Definition(dst), bld.def(s1, scc), src);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1253,9 +1262,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
bld.pseudo(aco_opcode::p_create_vector, Definition(dst), lower, upper);
}
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1266,9 +1273,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
Temp src = get_alu_src(ctx, instr->src[0]);
bld.vop2(aco_opcode::v_max_i32, Definition(dst), src, bld.vsub32(bld.def(v1), Operand(0u), src));
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1296,9 +1301,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
upper = bld.vop2(aco_opcode::v_cndmask_b32, bld.def(v1), Operand(0u), neg, gtz);
bld.pseudo(aco_opcode::p_create_vector, Definition(dst), lower, upper);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1308,9 +1311,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} else if (dst.regClass() == s1) {
emit_sop2_instruction(ctx, instr, aco_opcode::s_max_i32, dst, true);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1320,9 +1321,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} else if (dst.regClass() == s1) {
emit_sop2_instruction(ctx, instr, aco_opcode::s_max_u32, dst, true);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1332,9 +1331,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} else if (dst.regClass() == s1) {
emit_sop2_instruction(ctx, instr, aco_opcode::s_min_i32, dst, true);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1344,9 +1341,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} else if (dst.regClass() == s1) {
emit_sop2_instruction(ctx, instr, aco_opcode::s_min_u32, dst, true);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1362,9 +1357,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} else if (dst.regClass() == s2) {
emit_sop2_instruction(ctx, instr, aco_opcode::s_or_b64, dst, true);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1380,9 +1373,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} else if (dst.regClass() == s2) {
emit_sop2_instruction(ctx, instr, aco_opcode::s_and_b64, dst, true);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1398,9 +1389,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} else if (dst.regClass() == s2) {
emit_sop2_instruction(ctx, instr, aco_opcode::s_xor_b64, dst, true);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1418,9 +1407,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} else if (dst.regClass() == s1) {
emit_sop2_instruction(ctx, instr, aco_opcode::s_lshr_b32, dst, true);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1438,9 +1425,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} else if (dst.regClass() == s2) {
emit_sop2_instruction(ctx, instr, aco_opcode::s_lshl_b64, dst, true);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1458,9 +1443,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} else if (dst.regClass() == s2) {
emit_sop2_instruction(ctx, instr, aco_opcode::s_ashr_i64, dst, true);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1473,9 +1456,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} else if (src.regClass() == s2) {
bld.sop1(aco_opcode::s_ff1_i32_b64, Definition(dst), src);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1502,9 +1483,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
Temp carry = bld.vsub32(Definition(msb), Operand(31u), Operand(msb_rev), true).def(1).getTemp();
bld.vop2_e64(aco_opcode::v_cndmask_b32, Definition(dst), msb, Operand((uint32_t)-1), carry);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1514,9 +1493,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} else if (dst.regClass() == v1) {
bld.vop1(aco_opcode::v_bfrev_b32, Definition(dst), get_alu_src(ctx, instr->src[0]));
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1552,9 +1529,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
Temp dst1 = bld.vadd32(bld.def(v1), src01, src11, false, carry);
bld.pseudo(aco_opcode::p_create_vector, Definition(dst), dst0, dst1);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1583,9 +1558,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
bld.vop2_e64(aco_opcode::v_cndmask_b32, Definition(dst), tmp, Operand((uint32_t) -1), carry);
}
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1619,9 +1592,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
carry = bld.vop2_e64(aco_opcode::v_cndmask_b32, bld.def(v1), Operand(0u), Operand(1u), carry);
bld.pseudo(aco_opcode::p_create_vector, Definition(dst), carry, Operand(0u));
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1655,9 +1626,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
Temp upper = bld.vsub32(bld.def(v1), src01, src11, false, borrow);
bld.pseudo(aco_opcode::p_create_vector, Definition(dst), lower, upper);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1690,9 +1659,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
borrow = bld.vop2_e64(aco_opcode::v_cndmask_b32, bld.def(v1), Operand(0u), Operand(1u), borrow);
bld.pseudo(aco_opcode::p_create_vector, Definition(dst), borrow, Operand(0u));
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1703,9 +1670,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} else if (dst.regClass() == s1) {
emit_sop2_instruction(ctx, instr, aco_opcode::s_mul_i32, dst, false);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1719,9 +1684,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
as_vgpr(ctx, get_alu_src(ctx, instr->src[1])));
bld.pseudo(aco_opcode::p_as_uniform, Definition(dst), tmp);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1735,9 +1698,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
as_vgpr(ctx, get_alu_src(ctx, instr->src[1])));
bld.pseudo(aco_opcode::p_as_uniform, Definition(dst), tmp);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1751,9 +1712,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} else if (dst.regClass() == v2) {
bld.vop3(aco_opcode::v_mul_f64, Definition(dst), src0, src1);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1767,9 +1726,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} else if (dst.regClass() == v2) {
bld.vop3(aco_opcode::v_add_f64, Definition(dst), src0, src1);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1792,9 +1749,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
VOP3A_instruction* sub = static_cast<VOP3A_instruction*>(add);
sub->neg[1] = true;
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1814,9 +1769,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
bld.vop3(aco_opcode::v_max_f64, Definition(dst), src0, src1);
}
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1836,9 +1789,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
bld.vop3(aco_opcode::v_min_f64, Definition(dst), src0, src1);
}
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1848,9 +1799,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} else if (dst.regClass() == v1) {
emit_vop3a_instruction(ctx, instr, aco_opcode::v_max3_f32, dst, ctx->block->fp_mode.must_flush_denorms32);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1860,9 +1809,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} else if (dst.regClass() == v1) {
emit_vop3a_instruction(ctx, instr, aco_opcode::v_min3_f32, dst, ctx->block->fp_mode.must_flush_denorms32);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1872,9 +1819,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} else if (dst.regClass() == v1) {
emit_vop3a_instruction(ctx, instr, aco_opcode::v_med3_f32, dst, ctx->block->fp_mode.must_flush_denorms32);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1882,9 +1827,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
if (dst.size() == 1) {
emit_vop3a_instruction(ctx, instr, aco_opcode::v_max3_u32, dst);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1892,9 +1835,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
if (dst.size() == 1) {
emit_vop3a_instruction(ctx, instr, aco_opcode::v_min3_u32, dst);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1902,9 +1843,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
if (dst.size() == 1) {
emit_vop3a_instruction(ctx, instr, aco_opcode::v_med3_u32, dst);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1912,9 +1851,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
if (dst.size() == 1) {
emit_vop3a_instruction(ctx, instr, aco_opcode::v_max3_i32, dst);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1922,9 +1859,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
if (dst.size() == 1) {
emit_vop3a_instruction(ctx, instr, aco_opcode::v_min3_i32, dst);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1932,9 +1867,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
if (dst.size() == 1) {
emit_vop3a_instruction(ctx, instr, aco_opcode::v_med3_i32, dst);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -1976,9 +1909,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
/* Lowered at NIR level for precision reasons. */
emit_vop1_instruction(ctx, instr, aco_opcode::v_rsq_f64, dst);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -2000,9 +1931,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
upper = bld.vop2(aco_opcode::v_xor_b32, bld.def(v1), Operand(0x80000000u), upper);
bld.pseudo(aco_opcode::p_create_vector, Definition(dst), lower, upper);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -2024,9 +1953,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
upper = bld.vop2(aco_opcode::v_and_b32, bld.def(v1), Operand(0x7FFFFFFFu), upper);
bld.pseudo(aco_opcode::p_create_vector, Definition(dst), lower, upper);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -2043,9 +1970,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
VOP3A_instruction* vop3 = static_cast<VOP3A_instruction*>(add);
vop3->clamp = true;
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -2056,9 +1981,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} else if (dst.regClass() == v1) {
emit_log2(ctx, bld, Definition(dst), src);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -2072,9 +1995,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
/* Lowered at NIR level for precision reasons. */
emit_vop1_instruction(ctx, instr, aco_opcode::v_rcp_f64, dst);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -2084,9 +2005,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} else if (dst.regClass() == v1) {
emit_vop1_instruction(ctx, instr, aco_opcode::v_exp_f32, dst);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -2100,9 +2019,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
/* Lowered at NIR level for precision reasons. */
emit_vop1_instruction(ctx, instr, aco_opcode::v_sqrt_f64, dst);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -2114,9 +2031,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} else if (dst.regClass() == v2) {
emit_vop1_instruction(ctx, instr, aco_opcode::v_fract_f64, dst);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -2129,9 +2044,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} else if (dst.regClass() == v2) {
emit_floor_f64(ctx, bld, Definition(dst), src);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -2159,9 +2072,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
bld.vop3(aco_opcode::v_add_f64, Definition(dst), trunc, add);
}
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -2174,9 +2085,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} else if (dst.regClass() == v2) {
emit_trunc_f64(ctx, bld, Definition(dst), src);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -2214,9 +2123,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
bld.pseudo(aco_opcode::p_create_vector, Definition(dst), dst0, dst1);
}
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -2240,9 +2147,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
aco_opcode opcode = instr->op == nir_op_fsin ? aco_opcode::v_sin_f32 : aco_opcode::v_cos_f32;
bld.vop1(opcode, Definition(dst), tmp);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -2256,9 +2161,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} else if (dst.regClass() == v2) {
bld.vop3(aco_opcode::v_ldexp_f64, Definition(dst), as_vgpr(ctx, src0), src1);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -2271,9 +2174,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} else if (dst.regClass() == v2) {
bld.vop1(aco_opcode::v_frexp_mant_f64, Definition(dst), src);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -2288,9 +2189,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} else if (instr->src[0].src.ssa->bit_size == 64) {
bld.vop1(aco_opcode::v_frexp_exp_i32_f64, Definition(dst), src);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -2319,9 +2218,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
bld.pseudo(aco_opcode::p_create_vector, Definition(dst), Operand(0u), upper);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -2352,9 +2249,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} else if (instr->src[0].src.ssa->bit_size == 64) {
emit_vop1_instruction(ctx, instr, aco_opcode::v_cvt_f32_f64, dst);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -2400,9 +2295,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
bld.vop3(aco_opcode::v_add_f64, Definition(dst), lower, upper);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -2444,9 +2337,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
upper = bld.vop3(aco_opcode::v_ldexp_f64, bld.def(v2), upper, Operand(32u));
bld.vop3(aco_opcode::v_add_f64, Definition(dst), lower, upper);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -2485,9 +2376,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} else if (instr->src[0].src.ssa->bit_size == 64) {
emit_vop1_instruction(ctx, instr, aco_opcode::v_cvt_i32_f64, dst);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -2506,9 +2395,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} else if (instr->src[0].src.ssa->bit_size == 64) {
emit_vop1_instruction(ctx, instr, aco_opcode::v_cvt_u32_f64, dst);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -2585,9 +2472,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
bld.pseudo(aco_opcode::p_create_vector, Definition(dst), lower, upper);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -2657,9 +2542,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
bld.pseudo(aco_opcode::p_create_vector, Definition(dst), lower, upper);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -2838,9 +2721,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
bld.vop1(aco_opcode::v_cvt_f32_f16, bld.def(v1), src0),
bld.vop1(aco_opcode::v_cvt_f32_f16, bld.def(v1), src1));
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -2848,9 +2729,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
if (dst.regClass() == v1) {
bld.vop1(aco_opcode::v_cvt_f32_f16, Definition(dst), get_alu_src(ctx, instr->src[0]));
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -2860,9 +2739,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
bld.vop1(aco_opcode::v_cvt_f32_f16, Definition(dst),
bld.vop2(aco_opcode::v_lshrrev_b32, bld.def(v1), Operand(16u), as_vgpr(ctx, get_alu_src(ctx, instr->src[0]))));
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -2903,9 +2780,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} else if (dst.regClass() == v1) {
bld.vop3(aco_opcode::v_bfm_b32, Definition(dst), bits, offset);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -2948,9 +2823,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
bld.vop3(aco_opcode::v_bfi_b32, Definition(dst), bitmask, insert, base);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -3023,9 +2896,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
} else if (src.regClass() == s2) {
bld.sop1(aco_opcode::s_bcnt1_i32_b64, Definition(dst), bld.def(s1, scc), src);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -3112,9 +2983,7 @@ void visit_alu_instr(isel_context *ctx, nir_alu_instr *instr)
break;
}
default:
fprintf(stderr, "Unknown NIR ALU instr: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unknown NIR ALU instr");
}
}
@ -4521,9 +4390,7 @@ void visit_store_output(isel_context *ctx, nir_intrinsic_instr *instr)
ctx->shader->info.stage == MESA_SHADER_GEOMETRY) {
bool stored_to_temps = store_output_to_temps(ctx, instr);
if (!stored_to_temps) {
fprintf(stderr, "Unimplemented output offset instruction:\n");
nir_print_instr(instr->src[1].ssa->parent_instr, stderr);
fprintf(stderr, "\n");
isel_err(instr->src[1].ssa->parent_instr, "Unimplemented output offset instruction");
abort();
}
} else if (ctx->stage == vertex_es ||
@ -4740,9 +4607,7 @@ void visit_load_input(isel_context *ctx, nir_intrinsic_instr *instr)
nir_instr *off_instr = instr->src[0].ssa->parent_instr;
if (off_instr->type != nir_instr_type_load_const) {
fprintf(stderr, "Unimplemented nir_intrinsic_load_input offset\n");
nir_print_instr(off_instr, stderr);
fprintf(stderr, "\n");
isel_err(off_instr, "Unimplemented nir_intrinsic_load_input offset");
}
uint32_t offset = nir_instr_as_load_const(off_instr)->value[0].u32;
@ -4954,9 +4819,7 @@ void visit_load_input(isel_context *ctx, nir_intrinsic_instr *instr)
nir_instr *off_instr = instr->src[offset_idx].ssa->parent_instr;
if (off_instr->type != nir_instr_type_load_const ||
nir_instr_as_load_const(off_instr)->value[0].u32 != 0) {
fprintf(stderr, "Unimplemented nir_intrinsic_load_input offset\n");
nir_print_instr(off_instr, stderr);
fprintf(stderr, "\n");
isel_err(off_instr, "Unimplemented nir_intrinsic_load_input offset");
}
Temp prim_mask = get_arg(ctx, ctx->args->ac.prim_mask);
@ -7263,9 +7126,7 @@ void emit_uniform_subgroup(isel_context *ctx, nir_intrinsic_instr *instr, Temp s
} else if (src.regClass() == s2) {
bld.sop1(aco_opcode::s_mov_b64, dst, src);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
}
@ -7696,9 +7557,7 @@ void visit_intrinsic(isel_context *ctx, nir_intrinsic_instr *instr)
} else if (instr->src[0].ssa->bit_size == 64 && src.regClass() == v2) {
bld.vopc(aco_opcode::v_cmp_lg_u64, lanemask_tmp, Operand(0u), src);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
if (dst.size() != bld.lm.size()) {
/* Wave32 with ballot size set to 64 */
@ -7750,9 +7609,7 @@ void visit_intrinsic(isel_context *ctx, nir_intrinsic_instr *instr)
tmp = bld.vop2(aco_opcode::v_and_b32, bld.def(v1), Operand(1u), tmp);
emit_wqm(ctx, bld.vopc(aco_opcode::v_cmp_lg_u32, bld.def(bld.lm), Operand(0u), tmp), dst);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
}
break;
@ -7790,9 +7647,7 @@ void visit_intrinsic(isel_context *ctx, nir_intrinsic_instr *instr)
} else if (src.regClass() == s2) {
bld.pseudo(aco_opcode::p_create_vector, Definition(dst), src);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -7963,9 +7818,7 @@ void visit_intrinsic(isel_context *ctx, nir_intrinsic_instr *instr)
bld.pseudo(aco_opcode::p_create_vector, Definition(dst), lo, hi);
emit_split_vector(ctx, dst, 2);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
}
break;
@ -8043,9 +7896,7 @@ void visit_intrinsic(isel_context *ctx, nir_intrinsic_instr *instr)
bld.pseudo(aco_opcode::p_create_vector, Definition(dst), lo, hi);
emit_split_vector(ctx, dst, 2);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -8079,9 +7930,7 @@ void visit_intrinsic(isel_context *ctx, nir_intrinsic_instr *instr)
bld.pseudo(aco_opcode::p_create_vector, Definition(dst), lo, hi);
emit_split_vector(ctx, dst, 2);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -8103,9 +7952,7 @@ void visit_intrinsic(isel_context *ctx, nir_intrinsic_instr *instr)
bld.pseudo(aco_opcode::p_create_vector, Definition(dst), lo, hi);
emit_split_vector(ctx, dst, 2);
} else {
fprintf(stderr, "Unimplemented NIR instr bit size: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
break;
}
@ -8256,9 +8103,7 @@ void visit_intrinsic(isel_context *ctx, nir_intrinsic_instr *instr)
break;
}
default:
fprintf(stderr, "Unimplemented intrinsic instr: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unimplemented intrinsic instr");
abort();
break;
@ -9325,9 +9170,7 @@ void visit_jump(isel_context *ctx, nir_jump_instr *instr)
}
break;
default:
fprintf(stderr, "Unknown NIR jump instr: ");
nir_print_instr(&instr->instr, stderr);
fprintf(stderr, "\n");
isel_err(&instr->instr, "Unknown NIR jump instr");
abort();
}
@ -9385,9 +9228,7 @@ void visit_block(isel_context *ctx, nir_block *block)
visit_jump(ctx, nir_instr_as_jump(instr));
break;
default:
fprintf(stderr, "Unknown NIR instr type: ");
nir_print_instr(instr, stderr);
fprintf(stderr, "\n");
isel_err(instr, "Unknown NIR instr type");
//abort();
}
}

View File

@ -48,7 +48,7 @@ static void validate(aco::Program *program)
if (!(aco::debug_flags & aco::DEBUG_VALIDATE_IR))
return;
bool is_valid = aco::validate_ir(program, stderr);
bool is_valid = aco::validate_ir(program);
assert(is_valid);
}
@ -121,7 +121,7 @@ void aco_compile_shader(unsigned shader_count,
aco_print_program(program.get(), stderr);
}
if (aco::validate_ra(program.get(), args->options, stderr)) {
if (aco::validate_ra(program.get(), args->options)) {
std::cerr << "Program after RA validation failure:\n";
aco_print_program(program.get(), stderr);
abort();

View File

@ -1665,10 +1665,10 @@ void insert_NOPs(Program* program);
unsigned emit_program(Program* program, std::vector<uint32_t>& code);
void print_asm(Program *program, std::vector<uint32_t>& binary,
unsigned exec_size, std::ostream& out);
bool validate_ir(Program* program, FILE *output);
bool validate_ra(Program* program, const struct radv_nir_compiler_options *options, FILE *output);
bool validate_ir(Program* program);
bool validate_ra(Program* program, const struct radv_nir_compiler_options *options);
#ifndef NDEBUG
void perfwarn(bool cond, const char *msg, Instruction *instr=NULL);
void perfwarn(Program *program, bool cond, const char *msg, Instruction *instr=NULL);
#else
#define perfwarn(program, cond, msg, ...) do {} while(0)
#endif
@ -1680,6 +1680,14 @@ void collect_postasm_stats(Program *program, const std::vector<uint32_t>& code);
void aco_print_instr(const Instruction *instr, FILE *output);
void aco_print_program(const Program *program, FILE *output);
void _aco_perfwarn(Program *program, const char *file, unsigned line,
const char *fmt, ...);
void _aco_err(Program *program, const char *file, unsigned line,
const char *fmt, ...);
#define aco_perfwarn(program, ...) _aco_perfwarn(program, __FILE__, __LINE__, __VA_ARGS__)
#define aco_err(program, ...) _aco_err(program, __FILE__, __LINE__, __VA_ARGS__)
/* utilities for dealing with register demand */
RegisterDemand get_live_changes(aco_ptr<Instruction>& instr);
RegisterDemand get_temp_registers(aco_ptr<Instruction>& instr);

View File

@ -214,7 +214,7 @@ void process_live_temps_per_block(Program *program, live& lives, Block* block,
#ifndef NDEBUG
if (preds.empty())
fprintf(stderr, "Temporary never defined or are defined after use: %%%d in BB%d\n", t.id(), block->index);
aco_err(program, "Temporary never defined or are defined after use: %%%d in BB%d", t.id(), block->index);
#endif
for (unsigned pred_idx : preds) {

View File

@ -34,6 +34,27 @@
namespace aco {
#ifndef NDEBUG
void perfwarn(Program *program, bool cond, const char *msg, Instruction *instr)
{
if (cond) {
char *out;
size_t outsize;
FILE *memf = open_memstream(&out, &outsize);
fprintf(memf, "%s: ", msg);
aco_print_instr(instr, memf);
fclose(memf);
aco_perfwarn(program, out);
free(out);
if (debug_flags & DEBUG_PERFWARN)
exit(1);
}
}
#endif
/**
* The optimizer works in 4 phases:
* (1) The first pass collects information for each ssa-def,
@ -803,7 +824,7 @@ void label_instruction(opt_ctx &ctx, Block& block, aco_ptr<Instruction>& instr)
ASSERTED bool all_const = false;
for (Operand& op : instr->operands)
all_const = all_const && (!op.isTemp() || ctx.info[op.tempId()].is_constant_or_literal(32));
perfwarn(all_const, "All instruction operands are constant", instr.get());
perfwarn(ctx.program, all_const, "All instruction operands are constant", instr.get());
}
for (unsigned i = 0; i < instr->operands.size(); i++)
@ -905,7 +926,7 @@ void label_instruction(opt_ctx &ctx, Block& block, aco_ptr<Instruction>& instr)
unsigned bits = get_operand_size(instr, i);
if (info.is_constant(bits) && alu_can_accept_constant(instr->opcode, i)) {
Operand op = get_constant_op(ctx, info, bits);
perfwarn(instr->opcode == aco_opcode::v_cndmask_b32 && i == 2, "v_cndmask_b32 with a constant selector", instr.get());
perfwarn(ctx.program, instr->opcode == aco_opcode::v_cndmask_b32 && i == 2, "v_cndmask_b32 with a constant selector", instr.get());
if (i == 0 || instr->opcode == aco_opcode::v_readlane_b32 || instr->opcode == aco_opcode::v_writelane_b32) {
instr->operands[i] = op;
continue;

View File

@ -1259,7 +1259,7 @@ PhysReg get_reg(ra_ctx& ctx,
//FIXME: if nothing helps, shift-rotate the registers to make space
fprintf(stderr, "ACO: failed to allocate registers during shader compilation\n");
aco_err(ctx.program, "Failed to allocate registers during shader compilation.");
abort();
}

View File

@ -29,37 +29,68 @@
namespace aco {
#ifndef NDEBUG
void perfwarn(bool cond, const char *msg, Instruction *instr)
static void aco_log(Program *program, const char *prefix,
const char *file, unsigned line,
const char *fmt, va_list args)
{
if (cond) {
fprintf(stderr, "ACO performance warning: %s\n", msg);
if (instr) {
fprintf(stderr, "instruction: ");
aco_print_instr(instr, stderr);
fprintf(stderr, "\n");
}
char *msg;
if (debug_flags & DEBUG_PERFWARN)
exit(1);
}
msg = ralloc_strdup(NULL, prefix);
ralloc_asprintf_append(&msg, " In file %s:%u\n", file, line);
ralloc_asprintf_append(&msg, " ");
ralloc_vasprintf_append(&msg, fmt, args);
/* TODO: log messages via callback if available too. */
fprintf(stderr, "%s\n", msg);
ralloc_free(msg);
}
#endif
bool validate_ir(Program* program, FILE *output)
void _aco_perfwarn(Program *program, const char *file, unsigned line,
const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
aco_log(program, "ACO PERFWARN:\n", file, line, fmt, args);
va_end(args);
}
void _aco_err(Program *program, const char *file, unsigned line,
const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
aco_log(program, "ACO ERROR:\n", file, line, fmt, args);
va_end(args);
}
bool validate_ir(Program* program)
{
bool is_valid = true;
auto check = [&output, &is_valid](bool check, const char * msg, aco::Instruction * instr) -> void {
auto check = [&program, &is_valid](bool check, const char * msg, aco::Instruction * instr) -> void {
if (!check) {
fprintf(output, "%s: ", msg);
aco_print_instr(instr, output);
fprintf(output, "\n");
char *out;
size_t outsize;
FILE *memf = open_memstream(&out, &outsize);
fprintf(memf, "%s: ", msg);
aco_print_instr(instr, memf);
fclose(memf);
aco_err(program, out);
free(out);
is_valid = false;
}
};
auto check_block = [&output, &is_valid](bool check, const char * msg, aco::Block * block) -> void {
auto check_block = [&program, &is_valid](bool check, const char * msg, aco::Block * block) -> void {
if (!check) {
fprintf(output, "%s: BB%u\n", msg, block->index);
aco_err(program, "%s: BB%u", msg, block->index);
is_valid = false;
}
};
@ -455,25 +486,32 @@ struct Assignment {
PhysReg reg;
};
bool ra_fail(FILE *output, Location loc, Location loc2, const char *fmt, ...) {
bool ra_fail(Program *program, Location loc, Location loc2, const char *fmt, ...) {
va_list args;
va_start(args, fmt);
char msg[1024];
vsprintf(msg, fmt, args);
va_end(args);
fprintf(stderr, "RA error found at instruction in BB%d:\n", loc.block->index);
char *out;
size_t outsize;
FILE *memf = open_memstream(&out, &outsize);
fprintf(memf, "RA error found at instruction in BB%d:\n", loc.block->index);
if (loc.instr) {
aco_print_instr(loc.instr, stderr);
fprintf(stderr, "\n%s", msg);
aco_print_instr(loc.instr, memf);
fprintf(memf, "\n%s", msg);
} else {
fprintf(stderr, "%s", msg);
fprintf(memf, "%s", msg);
}
if (loc2.block) {
fprintf(stderr, " in BB%d:\n", loc2.block->index);
aco_print_instr(loc2.instr, stderr);
fprintf(memf, " in BB%d:\n", loc2.block->index);
aco_print_instr(loc2.instr, memf);
}
fprintf(stderr, "\n\n");
fprintf(memf, "\n\n");
aco_err(program, out);
free(out);
return true;
}
@ -610,7 +648,7 @@ unsigned get_subdword_bytes_written(Program *program, const aco_ptr<Instruction>
} /* end namespace */
bool validate_ra(Program *program, const struct radv_nir_compiler_options *options, FILE *output) {
bool validate_ra(Program *program, const struct radv_nir_compiler_options *options) {
if (!(debug_flags & DEBUG_VALIDATE_RA))
return false;
@ -638,16 +676,16 @@ bool validate_ra(Program *program, const struct radv_nir_compiler_options *optio
if (!op.isTemp())
continue;
if (!op.isFixed())
err |= ra_fail(output, loc, Location(), "Operand %d is not assigned a register", i);
err |= ra_fail(program, loc, Location(), "Operand %d is not assigned a register", i);
if (assignments.count(op.tempId()) && assignments[op.tempId()].reg != op.physReg())
err |= ra_fail(output, loc, assignments.at(op.tempId()).firstloc, "Operand %d has an inconsistent register assignment with instruction", i);
err |= ra_fail(program, loc, assignments.at(op.tempId()).firstloc, "Operand %d has an inconsistent register assignment with instruction", i);
if ((op.getTemp().type() == RegType::vgpr && op.physReg().reg_b + op.bytes() > (256 + program->config->num_vgprs) * 4) ||
(op.getTemp().type() == RegType::sgpr && op.physReg() + op.size() > program->config->num_sgprs && op.physReg() < program->sgpr_limit))
err |= ra_fail(output, loc, assignments.at(op.tempId()).firstloc, "Operand %d has an out-of-bounds register assignment", i);
err |= ra_fail(program, loc, assignments.at(op.tempId()).firstloc, "Operand %d has an out-of-bounds register assignment", i);
if (op.physReg() == vcc && !program->needs_vcc)
err |= ra_fail(output, loc, Location(), "Operand %d fixed to vcc but needs_vcc=false", i);
err |= ra_fail(program, loc, Location(), "Operand %d fixed to vcc but needs_vcc=false", i);
if (op.regClass().is_subdword() && !validate_subdword_operand(program->chip_class, instr, i))
err |= ra_fail(output, loc, Location(), "Operand %d not aligned correctly", i);
err |= ra_fail(program, loc, Location(), "Operand %d not aligned correctly", i);
if (!assignments[op.tempId()].firstloc.block)
assignments[op.tempId()].firstloc = loc;
if (!assignments[op.tempId()].defloc.block)
@ -659,16 +697,16 @@ bool validate_ra(Program *program, const struct radv_nir_compiler_options *optio
if (!def.isTemp())
continue;
if (!def.isFixed())
err |= ra_fail(output, loc, Location(), "Definition %d is not assigned a register", i);
err |= ra_fail(program, loc, Location(), "Definition %d is not assigned a register", i);
if (assignments[def.tempId()].defloc.block)
err |= ra_fail(output, loc, assignments.at(def.tempId()).defloc, "Temporary %%%d also defined by instruction", def.tempId());
err |= ra_fail(program, loc, assignments.at(def.tempId()).defloc, "Temporary %%%d also defined by instruction", def.tempId());
if ((def.getTemp().type() == RegType::vgpr && def.physReg().reg_b + def.bytes() > (256 + program->config->num_vgprs) * 4) ||
(def.getTemp().type() == RegType::sgpr && def.physReg() + def.size() > program->config->num_sgprs && def.physReg() < program->sgpr_limit))
err |= ra_fail(output, loc, assignments.at(def.tempId()).firstloc, "Definition %d has an out-of-bounds register assignment", i);
err |= ra_fail(program, loc, assignments.at(def.tempId()).firstloc, "Definition %d has an out-of-bounds register assignment", i);
if (def.physReg() == vcc && !program->needs_vcc)
err |= ra_fail(output, loc, Location(), "Definition %d fixed to vcc but needs_vcc=false", i);
err |= ra_fail(program, loc, Location(), "Definition %d fixed to vcc but needs_vcc=false", i);
if (def.regClass().is_subdword() && !validate_subdword_definition(program->chip_class, instr))
err |= ra_fail(output, loc, Location(), "Definition %d not aligned correctly", i);
err |= ra_fail(program, loc, Location(), "Definition %d not aligned correctly", i);
if (!assignments[def.tempId()].firstloc.block)
assignments[def.tempId()].firstloc = loc;
assignments[def.tempId()].defloc = loc;
@ -695,7 +733,7 @@ bool validate_ra(Program *program, const struct radv_nir_compiler_options *optio
PhysReg reg = assignments.at(tmp.id()).reg;
for (unsigned i = 0; i < tmp.bytes(); i++) {
if (regs[reg.reg_b + i]) {
err |= ra_fail(output, loc, Location(), "Assignment of element %d of %%%d already taken by %%%d in live-out", i, tmp.id(), regs[reg.reg_b + i]);
err |= ra_fail(program, loc, Location(), "Assignment of element %d of %%%d already taken by %%%d in live-out", i, tmp.id(), regs[reg.reg_b + i]);
}
regs[reg.reg_b + i] = tmp.id();
}
@ -711,7 +749,7 @@ bool validate_ra(Program *program, const struct radv_nir_compiler_options *optio
PhysReg reg = assignments.at(tmp.id()).reg;
for (unsigned i = 0; i < tmp.bytes(); i++) {
if (regs[reg.reg_b + i])
err |= ra_fail(output, loc, Location(), "Assignment of element %d of %%%d already taken by %%%d in live-out", i, tmp.id(), regs[reg.reg_b + i]);
err |= ra_fail(program, loc, Location(), "Assignment of element %d of %%%d already taken by %%%d in live-out", i, tmp.id(), regs[reg.reg_b + i]);
}
live.emplace(tmp);
}
@ -771,7 +809,7 @@ bool validate_ra(Program *program, const struct radv_nir_compiler_options *optio
PhysReg reg = assignments.at(tmp.id()).reg;
for (unsigned j = 0; j < tmp.bytes(); j++) {
if (regs[reg.reg_b + j])
err |= ra_fail(output, loc, assignments.at(regs[reg.reg_b + j]).defloc, "Assignment of element %d of %%%d already taken by %%%d from instruction", i, tmp.id(), regs[reg.reg_b + j]);
err |= ra_fail(program, loc, assignments.at(regs[reg.reg_b + j]).defloc, "Assignment of element %d of %%%d already taken by %%%d from instruction", i, tmp.id(), regs[reg.reg_b + j]);
regs[reg.reg_b + j] = tmp.id();
}
if (def.regClass().is_subdword() && def.bytes() < 4) {
@ -780,7 +818,7 @@ bool validate_ra(Program *program, const struct radv_nir_compiler_options *optio
for (unsigned j = reg.byte() & ~(written - 1); j < written; j++) {
unsigned written_reg = reg.reg() * 4u + j;
if (regs[written_reg] && regs[written_reg] != def.tempId())
err |= ra_fail(output, loc, assignments.at(regs[written_reg]).defloc, "Assignment of element %d of %%%d overwrites the full register taken by %%%d from instruction", i, tmp.id(), regs[written_reg]);
err |= ra_fail(program, loc, assignments.at(regs[written_reg]).defloc, "Assignment of element %d of %%%d overwrites the full register taken by %%%d from instruction", i, tmp.id(), regs[written_reg]);
}
}
}

View File

@ -146,7 +146,7 @@ void finish_validator_test()
finish_program(program.get());
aco_print_program(program.get(), output);
fprintf(output, "Validation results:\n");
if (aco::validate_ir(program.get(), output))
if (aco::validate_ir(program.get()))
fprintf(output, "Validation passed\n");
else
fprintf(output, "Validation failed\n");
@ -155,12 +155,12 @@ void finish_validator_test()
void finish_opt_test()
{
finish_program(program.get());
if (!aco::validate_ir(program.get(), output)) {
if (!aco::validate_ir(program.get())) {
fail_test("Validation before optimization failed");
return;
}
aco::optimize(program.get());
if (!aco::validate_ir(program.get(), output)) {
if (!aco::validate_ir(program.get())) {
fail_test("Validation after optimization failed");
return;
}