From cef01e817de517037135f768595696ccb8873af0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Tue, 19 Mar 2024 15:12:04 +0100 Subject: [PATCH] aco: use instr_class::branch to identify SOPP branches Also changes the instr_class of s_trap to instr_class::other. Part-of: --- src/amd/compiler/aco_assembler.cpp | 11 +++++---- src/amd/compiler/aco_lower_to_hw_instr.cpp | 25 ++++++++++++--------- src/amd/compiler/aco_opcodes.py | 2 +- src/amd/compiler/aco_print_ir.cpp | 2 +- src/amd/compiler/aco_statistics.cpp | 3 ++- src/amd/compiler/tests/test_insert_nops.cpp | 4 ++-- 6 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/amd/compiler/aco_assembler.cpp b/src/amd/compiler/aco_assembler.cpp index 41f03843f99..768f995b0fa 100644 --- a/src/amd/compiler/aco_assembler.cpp +++ b/src/amd/compiler/aco_assembler.cpp @@ -207,17 +207,20 @@ emit_sopc_instruction(asm_context& ctx, std::vector& out, Instruction* } void -emit_sopp_instruction(asm_context& ctx, std::vector& out, Instruction* instr) +emit_sopp_instruction(asm_context& ctx, std::vector& out, Instruction* instr, + bool force_imm = false) { uint32_t opcode = ctx.opcode[(int)instr->opcode]; SOPP_instruction& sopp = instr->sopp(); uint32_t encoding = (0b101111111 << 23); encoding |= opcode << 16; - encoding |= (uint16_t)sopp.imm; - if (sopp.block != -1) { + + if (!force_imm && instr_info.classes[(int)instr->opcode] == instr_class::branch) { sopp.pass_flags = 0; ctx.branches.emplace_back(out.size(), &sopp); + } else { + encoding |= (uint16_t)sopp.imm; } out.push_back(encoding); } @@ -1346,7 +1349,7 @@ emit_long_jump(asm_context& ctx, SOPP_instruction* branch, bool backwards, default: unreachable("Unhandled long jump."); } instr.reset(bld.sopp(inv, -1, 6)); - emit_instruction(ctx, out, instr.get()); + emit_sopp_instruction(ctx, out, instr.get(), true); } /* create the new PC and stash SCC in the LSB */ diff --git a/src/amd/compiler/aco_lower_to_hw_instr.cpp b/src/amd/compiler/aco_lower_to_hw_instr.cpp index 295d7833609..d62e0a530f5 100644 --- a/src/amd/compiler/aco_lower_to_hw_instr.cpp +++ b/src/amd/compiler/aco_lower_to_hw_instr.cpp @@ -2889,18 +2889,21 @@ lower_to_hw_instr(Program* program) for (aco_ptr& inst : program->blocks[i].instructions) { if (inst->isSOPP()) { - /* Discard early exits and loop breaks and continues should work fine with an - * empty exec mask. - */ - bool is_break_continue = - program->blocks[i].kind & (block_kind_break | block_kind_continue); - bool discard_early_exit = - inst->sopp().block != -1 && - (program->blocks[inst->sopp().block].kind & block_kind_discard_early_exit); - if ((inst->opcode != aco_opcode::s_cbranch_scc0 && - inst->opcode != aco_opcode::s_cbranch_scc1) || - (!discard_early_exit && !is_break_continue)) + if (instr_info.classes[(int)inst->opcode] == instr_class::branch) { + /* Discard early exits and loop breaks and continues should work fine with + * an empty exec mask. + */ + bool is_break_continue = + program->blocks[i].kind & (block_kind_break | block_kind_continue); + bool discard_early_exit = + program->blocks[inst->sopp().block].kind & block_kind_discard_early_exit; + if ((inst->opcode != aco_opcode::s_cbranch_scc0 && + inst->opcode != aco_opcode::s_cbranch_scc1) || + (!discard_early_exit && !is_break_continue)) + can_remove = false; + } else { can_remove = false; + } } else if (inst->isSALU()) { num_scalar++; } else if (inst->isVALU() || inst->isVINTRP()) { diff --git a/src/amd/compiler/aco_opcodes.py b/src/amd/compiler/aco_opcodes.py index 994c9159640..e15c046b31e 100644 --- a/src/amd/compiler/aco_opcodes.py +++ b/src/amd/compiler/aco_opcodes.py @@ -670,7 +670,7 @@ SOPP = { ("s_setprio", dst(), src(), op(0x0f, gfx11=0x35)), ("s_sendmsg", dst(), src(), op(0x10, gfx11=0x36), InstrClass.Sendmsg), ("s_sendmsghalt", dst(), src(), op(0x11, gfx11=0x37), InstrClass.Sendmsg), - ("s_trap", dst(), src(), op(0x12, gfx11=0x10), InstrClass.Branch), + ("s_trap", dst(), src(), op(0x12, gfx11=0x10), InstrClass.Other), ("s_icache_inv", dst(), src(), op(0x13, gfx11=0x3c)), ("s_incperflevel", dst(), src(), op(0x14, gfx11=0x38)), ("s_decperflevel", dst(), src(), op(0x15, gfx11=0x39)), diff --git a/src/amd/compiler/aco_print_ir.cpp b/src/amd/compiler/aco_print_ir.cpp index 3495035c2d3..58de0323838 100644 --- a/src/amd/compiler/aco_print_ir.cpp +++ b/src/amd/compiler/aco_print_ir.cpp @@ -404,7 +404,7 @@ print_instr_format_specific(enum amd_gfx_level gfx_level, const Instruction* ins break; } } - if (instr->sopp().block != -1) + if (instr_info.classes[(int)instr->opcode] == instr_class::branch) fprintf(output, " block:BB%d", instr->sopp().block); break; } diff --git a/src/amd/compiler/aco_statistics.cpp b/src/amd/compiler/aco_statistics.cpp index 5eb202b8ba7..30f3184eff7 100644 --- a/src/amd/compiler/aco_statistics.cpp +++ b/src/amd/compiler/aco_statistics.cpp @@ -531,7 +531,8 @@ collect_preasm_stats(Program* program) program->statistics[aco_statistic_instructions] += block.instructions.size(); for (aco_ptr& instr : block.instructions) { - bool is_branch = instr->isSOPP() && instr->sopp().block != -1; + const bool is_branch = + instr->isSOPP() && instr_info.classes[(int)instr->opcode] == instr_class::branch; if (is_branch) program->statistics[aco_statistic_branches]++; diff --git a/src/amd/compiler/tests/test_insert_nops.cpp b/src/amd/compiler/tests/test_insert_nops.cpp index e7efc83eb3e..89c66924e48 100644 --- a/src/amd/compiler/tests/test_insert_nops.cpp +++ b/src/amd/compiler/tests/test_insert_nops.cpp @@ -1187,13 +1187,13 @@ BEGIN_TEST(insert_nops.setpc_gfx10) //! p_unit_test 4 //! v1: %0:v[0] = ds_read_b32 %0:v[0] //! v_nop - //! s_branch + //! s_branch block:BB0 //! s_waitcnt_vscnt %0:null imm:0 //! s_setpc_b64 0 bld.pseudo(aco_opcode::p_unit_test, Operand::c32(4)); bld.ds(aco_opcode::ds_read_b32, Definition(PhysReg(256), v1), Operand(PhysReg(256), v1)); bld.vop1(aco_opcode::v_nop); /* reset VMEMtoScalarWriteHazard */ - bld.sopp(aco_opcode::s_branch, -1, 0); + bld.sopp(aco_opcode::s_branch, 0); bld.sop1(aco_opcode::s_setpc_b64, Operand::zero(8)); //! p_unit_test 5