diff --git a/src/amd/compiler/aco_assembler.cpp b/src/amd/compiler/aco_assembler.cpp index 1deb8b931cd..50b8715cdda 100644 --- a/src/amd/compiler/aco_assembler.cpp +++ b/src/amd/compiler/aco_assembler.cpp @@ -44,7 +44,7 @@ struct constaddr_info { struct asm_context { Program* program; enum amd_gfx_level gfx_level; - std::vector> branches; + std::vector> branches; std::map constaddrs; std::map resumeaddrs; std::vector* symbols; @@ -155,7 +155,8 @@ void emit_sopk_instruction(asm_context& ctx, std::vector& out, Instruction* instr) { uint32_t opcode = ctx.opcode[(int)instr->opcode]; - SOPK_instruction& sopk = instr->sopk(); + SALU_instruction& sopk = instr->salu(); + assert(sopk.imm <= UINT16_MAX); if (instr->opcode == aco_opcode::s_subvector_loop_begin) { assert(ctx.gfx_level >= GFX10); @@ -211,7 +212,7 @@ emit_sopp_instruction(asm_context& ctx, std::vector& out, Instruction* bool force_imm = false) { uint32_t opcode = ctx.opcode[(int)instr->opcode]; - SOPP_instruction& sopp = instr->sopp(); + SALU_instruction& sopp = instr->salu(); uint32_t encoding = (0b101111111 << 23); encoding |= opcode << 16; @@ -1316,7 +1317,7 @@ fix_branches_gfx10(asm_context& ctx, std::vector& out) } void -emit_long_jump(asm_context& ctx, SOPP_instruction* branch, bool backwards, +emit_long_jump(asm_context& ctx, SALU_instruction* branch, bool backwards, std::vector& out) { Builder bld(ctx.program); @@ -1384,7 +1385,7 @@ fix_branches(asm_context& ctx, std::vector& out) if (ctx.gfx_level == GFX10) fix_branches_gfx10(ctx, out); - for (std::pair& branch : ctx.branches) { + for (std::pair& branch : ctx.branches) { int offset = (int)ctx.program->blocks[branch.second->imm].offset - branch.first - 1; if ((offset < INT16_MIN || offset > INT16_MAX) && !branch.second->pass_flags) { std::vector long_jump; @@ -1461,7 +1462,7 @@ align_block(asm_context& ctx, std::vector& code, Block& block) insert_code(ctx, code, loop_header->offset, nops.size(), nops.data()); /* Change prefetch mode back to default (0x3). */ - instr->sopp().imm = 0x3; + instr->salu().imm = 0x3; emit_instruction(ctx, code, instr.get()); } diff --git a/src/amd/compiler/aco_builder_h.py b/src/amd/compiler/aco_builder_h.py index fd8fd237b62..733e866f094 100644 --- a/src/amd/compiler/aco_builder_h.py +++ b/src/amd/compiler/aco_builder_h.py @@ -566,11 +566,11 @@ public: <% import itertools formats = [("pseudo", [Format.PSEUDO], 'Pseudo_instruction', list(itertools.product(range(5), range(6))) + [(8, 1), (1, 8), (2, 6), (3, 6), (1, 6)]), - ("sop1", [Format.SOP1], 'SOP1_instruction', [(0, 1), (1, 0), (1, 1), (2, 1), (3, 2)]), - ("sop2", [Format.SOP2], 'SOP2_instruction', itertools.product([1, 2], [2, 3])), - ("sopk", [Format.SOPK], 'SOPK_instruction', itertools.product([0, 1, 2], [0, 1])), - ("sopp", [Format.SOPP], 'SOPP_instruction', itertools.product([0, 1], [0, 1])), - ("sopc", [Format.SOPC], 'SOPC_instruction', [(1, 2)]), + ("sop1", [Format.SOP1], 'SALU_instruction', [(0, 1), (1, 0), (1, 1), (2, 1), (3, 2)]), + ("sop2", [Format.SOP2], 'SALU_instruction', itertools.product([1, 2], [2, 3])), + ("sopk", [Format.SOPK], 'SALU_instruction', itertools.product([0, 1, 2], [0, 1])), + ("sopp", [Format.SOPP], 'SALU_instruction', itertools.product([0, 1], [0, 1])), + ("sopc", [Format.SOPC], 'SALU_instruction', [(1, 2)]), ("smem", [Format.SMEM], 'SMEM_instruction', [(0, 4), (0, 3), (1, 0), (1, 3), (1, 2), (1, 1), (0, 0)]), ("ds", [Format.DS], 'DS_instruction', [(1, 1), (1, 2), (1, 3), (0, 3), (0, 4)]), ("ldsdir", [Format.LDSDIR], 'LDSDIR_instruction', [(1, 1)]), diff --git a/src/amd/compiler/aco_insert_NOPs.cpp b/src/amd/compiler/aco_insert_NOPs.cpp index 82c37aac21e..f0500e1bbc0 100644 --- a/src/amd/compiler/aco_insert_NOPs.cpp +++ b/src/amd/compiler/aco_insert_NOPs.cpp @@ -313,7 +313,7 @@ int get_wait_states(aco_ptr& instr) { if (instr->opcode == aco_opcode::s_nop) - return instr->sopp().imm + 1; + return instr->salu().imm + 1; else if (instr->opcode == aco_opcode::p_constaddr) return 3; /* lowered to 3 instructions in the assembler */ else @@ -611,8 +611,8 @@ handle_instruction_gfx6(State& state, NOP_ctx_gfx6& ctx, aco_ptr& i // TODO: try to schedule the NOP-causing instruction up to reduce the number of stall cycles if (NOPs) { /* create NOP */ - aco_ptr nop{ - create_instruction(aco_opcode::s_nop, Format::SOPP, 0, 0)}; + aco_ptr nop{ + create_instruction(aco_opcode::s_nop, Format::SOPP, 0, 0)}; nop->imm = NOPs - 1; new_instructions.emplace_back(std::move(nop)); } @@ -668,7 +668,7 @@ handle_instruction_gfx6(State& state, NOP_ctx_gfx6& ctx, aco_ptr& i } } else if (instr->opcode == aco_opcode::s_setreg_b32 || instr->opcode == aco_opcode::s_setreg_imm32_b32) { - SOPK_instruction& sopk = instr->sopk(); + SALU_instruction& sopk = instr->salu(); unsigned offset = (sopk.imm >> 6) & 0x1f; unsigned size = ((sopk.imm >> 11) & 0x1f) + 1; unsigned reg = sopk.imm & 0x3f; @@ -900,8 +900,8 @@ handle_instruction_gfx10(State& state, NOP_ctx_gfx10& ctx, aco_ptr& vm_vsrc = 0; sa_sdst = 0; } else if (instr->opcode == aco_opcode::s_waitcnt_depctr) { - vm_vsrc = (instr->sopp().imm >> 2) & 0x7; - sa_sdst = instr->sopp().imm & 0x1; + vm_vsrc = (instr->salu().imm >> 2) & 0x7; + sa_sdst = instr->salu().imm & 0x1; } /* VMEMtoScalarWriteHazard @@ -918,12 +918,12 @@ handle_instruction_gfx10(State& state, NOP_ctx_gfx10& ctx, aco_ptr& mark_read_regs_exec(state, instr, ctx.sgprs_read_by_DS); } else if (instr->isSALU() || instr->isSMEM()) { if (instr->opcode == aco_opcode::s_waitcnt) { - wait_imm imm(state.program->gfx_level, instr->sopp().imm); + wait_imm imm(state.program->gfx_level, instr->salu().imm); if (imm.vm == 0) ctx.sgprs_read_by_VMEM.reset(); if (imm.lgkm == 0) ctx.sgprs_read_by_DS.reset(); - } else if (instr->opcode == aco_opcode::s_waitcnt_vscnt && instr->sopk().imm == 0) { + } else if (instr->opcode == aco_opcode::s_waitcnt_vscnt && instr->salu().imm == 0) { ctx.sgprs_read_by_VMEM_store.reset(); } else if (vm_vsrc == 0) { ctx.sgprs_read_by_VMEM.reset(); @@ -1002,11 +1002,11 @@ handle_instruction_gfx10(State& state, NOP_ctx_gfx10& ctx, aco_ptr& } else if (instr->isSALU()) { /* Reducing lgkmcnt count to 0 always mitigates the hazard. */ if (instr->opcode == aco_opcode::s_waitcnt_lgkmcnt) { - const SOPK_instruction& sopk = instr->sopk(); + const SALU_instruction& sopk = instr->salu(); if (sopk.imm == 0 && sopk.operands[0].physReg() == sgpr_null) ctx.sgprs_read_by_SMEM.reset(); } else if (instr->opcode == aco_opcode::s_waitcnt) { - wait_imm imm(state.program->gfx_level, instr->sopp().imm); + wait_imm imm(state.program->gfx_level, instr->salu().imm); if (imm.lgkm == 0) ctx.sgprs_read_by_SMEM.reset(); } else if (instr->format != Format::SOPP && instr->definitions.size()) { @@ -1034,7 +1034,7 @@ handle_instruction_gfx10(State& state, NOP_ctx_gfx10& ctx, aco_ptr& ctx.has_VMEM = ctx.has_DS = false; } else if (instr->opcode == aco_opcode::s_waitcnt_vscnt) { /* Only s_waitcnt_vscnt can mitigate the hazard */ - const SOPK_instruction& sopk = instr->sopk(); + const SALU_instruction& sopk = instr->salu(); if (sopk.operands[0].physReg() == sgpr_null && sopk.imm == 0) ctx.has_VMEM = ctx.has_branch_after_VMEM = ctx.has_DS = ctx.has_branch_after_DS = false; } @@ -1145,7 +1145,7 @@ parse_vdst_wait(aco_ptr& instr) else if (instr->isLDSDIR()) return instr->ldsdir().wait_vdst; else if (instr->opcode == aco_opcode::s_waitcnt_depctr) - return (instr->sopp().imm >> 12) & 0xf; + return (instr->salu().imm >> 12) & 0xf; else return 15; } @@ -1417,8 +1417,8 @@ handle_instruction_gfx11(State& state, NOP_ctx_gfx11& ctx, aco_ptr& sa_sdst = 0; } else if (instr->opcode == aco_opcode::s_waitcnt_depctr) { /* va_vdst already obtained through parse_vdst_wait(). */ - vm_vsrc = (instr->sopp().imm >> 2) & 0x7; - sa_sdst = instr->sopp().imm & 0x1; + vm_vsrc = (instr->salu().imm >> 2) & 0x7; + sa_sdst = instr->salu().imm & 0x1; } if (instr->isLDSDIR()) { @@ -1539,12 +1539,12 @@ handle_instruction_gfx11(State& state, NOP_ctx_gfx11& ctx, aco_ptr& ctx.vgpr_used_by_vmem_store.reset(); ctx.vgpr_used_by_ds.reset(); } else if (instr->opcode == aco_opcode::s_waitcnt) { - wait_imm imm(GFX11, instr->sopp().imm); + wait_imm imm(GFX11, instr->salu().imm); if (imm.vm == 0) ctx.vgpr_used_by_vmem_load.reset(); if (imm.lgkm == 0) ctx.vgpr_used_by_ds.reset(); - } else if (instr->opcode == aco_opcode::s_waitcnt_vscnt && instr->sopk().imm == 0) { + } else if (instr->opcode == aco_opcode::s_waitcnt_vscnt && instr->salu().imm == 0) { ctx.vgpr_used_by_vmem_store.reset(); } if (instr->isLDSDIR()) { diff --git a/src/amd/compiler/aco_insert_exec_mask.cpp b/src/amd/compiler/aco_insert_exec_mask.cpp index 7ab20c443ef..a4ba5783b7c 100644 --- a/src/amd/compiler/aco_insert_exec_mask.cpp +++ b/src/amd/compiler/aco_insert_exec_mask.cpp @@ -498,7 +498,7 @@ process_instructions(exec_ctx& ctx, Block* block, std::vectordefinitions[0]; assert(dst.size() == bld.lm.size()); if (state == Exact) { - instr.reset(create_instruction(bld.w64or32(Builder::s_mov), + instr.reset(create_instruction(bld.w64or32(Builder::s_mov), Format::SOP1, 1, 1)); instr->operands[0] = Operand::zero(); instr->definitions[0] = dst; @@ -506,7 +506,7 @@ process_instructions(exec_ctx& ctx, Block* block, std::vector& exact_mask = info.exec[0]; assert(exact_mask.second & mask_type_exact); - instr.reset(create_instruction(bld.w64or32(Builder::s_andn2), + instr.reset(create_instruction(bld.w64or32(Builder::s_andn2), Format::SOP2, 2, 2)); instr->operands[0] = Operand(exec, bld.lm); /* current exec */ instr->operands[1] = Operand(exact_mask.first); diff --git a/src/amd/compiler/aco_insert_waitcnt.cpp b/src/amd/compiler/aco_insert_waitcnt.cpp index af89ad48e29..b1f4722cc73 100644 --- a/src/amd/compiler/aco_insert_waitcnt.cpp +++ b/src/amd/compiler/aco_insert_waitcnt.cpp @@ -448,10 +448,10 @@ bool parse_wait_instr(wait_ctx& ctx, wait_imm& imm, Instruction* instr) { if (instr->opcode == aco_opcode::s_waitcnt_vscnt && instr->operands[0].physReg() == sgpr_null) { - imm.vs = std::min(imm.vs, instr->sopk().imm); + imm.vs = std::min(imm.vs, instr->salu().imm); return true; } else if (instr->opcode == aco_opcode::s_waitcnt) { - imm.combine(wait_imm(ctx.gfx_level, instr->sopp().imm)); + imm.combine(wait_imm(ctx.gfx_level, instr->salu().imm)); return true; } return false; @@ -463,7 +463,7 @@ parse_delay_alu(wait_ctx& ctx, alu_delay_info& delay, Instruction* instr) if (instr->opcode != aco_opcode::s_delay_alu) return false; - unsigned imm[2] = {instr->sopp().imm & 0xf, (instr->sopp().imm >> 7) & 0xf}; + unsigned imm[2] = {instr->salu().imm & 0xf, (instr->salu().imm >> 7) & 0xf}; for (unsigned i = 0; i < 2; ++i) { alu_delay_wait wait = (alu_delay_wait)imm[i]; if (wait >= alu_delay_wait::VALU_DEP_1 && wait <= alu_delay_wait::VALU_DEP_4) @@ -570,7 +570,7 @@ kill(wait_imm& imm, alu_delay_info& delay, Instruction* instr, wait_ctx& ctx, if (ctx.program->has_pops_overlapped_waves_wait && (ctx.gfx_level >= GFX11 ? instr->isEXP() && instr->exp().done : (instr->opcode == aco_opcode::s_sendmsg && - instr->sopp().imm == sendmsg_ordered_ps_done))) { + instr->salu().imm == sendmsg_ordered_ps_done))) { if (ctx.vm_nonzero) imm.vm = 0; if (ctx.gfx_level >= GFX10 && ctx.vs_nonzero) @@ -993,16 +993,16 @@ emit_waitcnt(wait_ctx& ctx, std::vector>& instructions, wai { if (imm.vs != wait_imm::unset_counter) { assert(ctx.gfx_level >= GFX10); - SOPK_instruction* waitcnt_vs = - create_instruction(aco_opcode::s_waitcnt_vscnt, Format::SOPK, 1, 0); + SALU_instruction* waitcnt_vs = + create_instruction(aco_opcode::s_waitcnt_vscnt, Format::SOPK, 1, 0); waitcnt_vs->operands[0] = Operand(sgpr_null, s1); waitcnt_vs->imm = imm.vs; instructions.emplace_back(waitcnt_vs); imm.vs = wait_imm::unset_counter; } if (!imm.empty()) { - SOPP_instruction* waitcnt = - create_instruction(aco_opcode::s_waitcnt, Format::SOPP, 0, 0); + SALU_instruction* waitcnt = + create_instruction(aco_opcode::s_waitcnt, Format::SOPP, 0, 0); waitcnt->imm = imm.pack(ctx.gfx_level); instructions.emplace_back(waitcnt); } @@ -1030,8 +1030,8 @@ emit_delay_alu(wait_ctx& ctx, std::vector>& instructions, imm |= ((uint32_t)alu_delay_wait::SALU_CYCLE_1 + cycles - 1) << (imm ? 7 : 0); } - SOPP_instruction* inst = - create_instruction(aco_opcode::s_delay_alu, Format::SOPP, 0, 0); + SALU_instruction* inst = + create_instruction(aco_opcode::s_delay_alu, Format::SOPP, 0, 0); inst->imm = imm; inst->pass_flags = (delay.valu_cycles | (delay.trans_cycles << 16)); instructions.emplace_back(inst); @@ -1176,7 +1176,7 @@ insert_wait_states(Program* program) continue; } - uint16_t imm = instr->sopp().imm; + uint16_t imm = instr->salu().imm; int skip = i - prev_delay_alu - 1; if (imm >> 7 || prev_delay_alu < 0 || skip >= 6) { if (imm >> 7 == 0) @@ -1185,7 +1185,7 @@ insert_wait_states(Program* program) continue; } - block.instructions[prev_delay_alu]->sopp().imm |= (skip << 4) | (imm << 7); + block.instructions[prev_delay_alu]->salu().imm |= (skip << 4) | (imm << 7); prev_delay_alu = -1; } block.instructions.resize(i); diff --git a/src/amd/compiler/aco_instruction_selection.cpp b/src/amd/compiler/aco_instruction_selection.cpp index 34c88417523..1460a27dfdd 100644 --- a/src/amd/compiler/aco_instruction_selection.cpp +++ b/src/amd/compiler/aco_instruction_selection.cpp @@ -823,8 +823,8 @@ void emit_sop2_instruction(isel_context* ctx, nir_alu_instr* instr, aco_opcode op, Temp dst, bool writes_scc, uint8_t uses_ub = 0) { - aco_ptr sop2{ - create_instruction(op, Format::SOP2, 2, writes_scc ? 2 : 1)}; + aco_ptr sop2{ + create_instruction(op, Format::SOP2, 2, writes_scc ? 2 : 1)}; sop2->operands[0] = Operand(get_alu_src(ctx, instr->src[0])); sop2->operands[1] = Operand(get_alu_src(ctx, instr->src[1])); sop2->definitions[0] = Definition(dst); diff --git a/src/amd/compiler/aco_ir.cpp b/src/amd/compiler/aco_ir.cpp index 866eb2452ae..ac0a623f1fa 100644 --- a/src/amd/compiler/aco_ir.cpp +++ b/src/amd/compiler/aco_ir.cpp @@ -231,7 +231,7 @@ get_sync_info(const Instruction* instr) */ if (instr->opcode == aco_opcode::p_pops_gfx9_overlapped_wave_wait_done || (instr->opcode == aco_opcode::s_wait_event && - !(instr->sopp().imm & wait_event_imm_dont_wait_export_ready))) { + !(instr->salu().imm & wait_event_imm_dont_wait_export_ready))) { return memory_sync_info(storage_buffer | storage_image, semantic_acquire, scope_queuefamily); } else if (instr->opcode == aco_opcode::p_pops_gfx9_ordered_section_done) { return memory_sync_info(storage_buffer | storage_image, semantic_release, scope_queuefamily); diff --git a/src/amd/compiler/aco_ir.h b/src/amd/compiler/aco_ir.h index 0921c2f6585..ccbdf64a426 100644 --- a/src/amd/compiler/aco_ir.h +++ b/src/amd/compiler/aco_ir.h @@ -939,11 +939,7 @@ private: struct Block; struct Instruction; struct Pseudo_instruction; -struct SOP1_instruction; -struct SOP2_instruction; -struct SOPK_instruction; -struct SOPP_instruction; -struct SOPC_instruction; +struct SALU_instruction; struct SMEM_instruction; struct DS_instruction; struct LDSDIR_instruction; @@ -1002,61 +998,13 @@ struct Instruction { return *(Pseudo_instruction*)this; } constexpr bool isPseudo() const noexcept { return format == Format::PSEUDO; } - SOP1_instruction& sop1() noexcept - { - assert(isSOP1()); - return *(SOP1_instruction*)this; - } - const SOP1_instruction& sop1() const noexcept - { - assert(isSOP1()); - return *(SOP1_instruction*)this; - } + constexpr bool isSOP1() const noexcept { return format == Format::SOP1; } - SOP2_instruction& sop2() noexcept - { - assert(isSOP2()); - return *(SOP2_instruction*)this; - } - const SOP2_instruction& sop2() const noexcept - { - assert(isSOP2()); - return *(SOP2_instruction*)this; - } constexpr bool isSOP2() const noexcept { return format == Format::SOP2; } - SOPK_instruction& sopk() noexcept - { - assert(isSOPK()); - return *(SOPK_instruction*)this; - } - const SOPK_instruction& sopk() const noexcept - { - assert(isSOPK()); - return *(SOPK_instruction*)this; - } constexpr bool isSOPK() const noexcept { return format == Format::SOPK; } - SOPP_instruction& sopp() noexcept - { - assert(isSOPP()); - return *(SOPP_instruction*)this; - } - const SOPP_instruction& sopp() const noexcept - { - assert(isSOPP()); - return *(SOPP_instruction*)this; - } constexpr bool isSOPP() const noexcept { return format == Format::SOPP; } - SOPC_instruction& sopc() noexcept - { - assert(isSOPC()); - return *(SOPC_instruction*)this; - } - const SOPC_instruction& sopc() const noexcept - { - assert(isSOPC()); - return *(SOPC_instruction*)this; - } constexpr bool isSOPC() const noexcept { return format == Format::SOPC; } + SMEM_instruction& smem() noexcept { assert(isSMEM()); @@ -1295,6 +1243,16 @@ struct Instruction { isVOPD(); } + SALU_instruction& salu() noexcept + { + assert(isSALU()); + return *(SALU_instruction*)this; + } + const SALU_instruction& salu() const noexcept + { + assert(isSALU()); + return *(SALU_instruction*)this; + } constexpr bool isSALU() const noexcept { return isSOP1() || isSOP2() || isSOPC() || isSOPK() || isSOPP(); @@ -1307,32 +1265,13 @@ struct Instruction { }; static_assert(sizeof(Instruction) == 16, "Unexpected padding"); -struct SOPK_instruction : public Instruction { - uint16_t imm; - uint16_t padding; -}; -static_assert(sizeof(SOPK_instruction) == sizeof(Instruction) + 4, "Unexpected padding"); - -struct SOPP_instruction : public Instruction { - /* In case of branch instructions, contains the Block index, - * and otherwise, the 16-bit signed immediate. +struct SALU_instruction : public Instruction { + /* In case of SOPP branch instructions, contains the Block index, + * and otherwise, for SOPP and SOPK the 16-bit signed immediate. */ uint32_t imm; }; -static_assert(sizeof(SOPP_instruction) == sizeof(Instruction) + 4, "Unexpected padding"); - -struct SOPC_instruction : public Instruction { - uint32_t padding; -}; -static_assert(sizeof(SOPC_instruction) == sizeof(Instruction) + 4, "Unexpected padding"); - -struct SOP1_instruction : public Instruction {}; -static_assert(sizeof(SOP1_instruction) == sizeof(Instruction) + 0, "Unexpected padding"); - -struct SOP2_instruction : public Instruction { - uint32_t padding; -}; -static_assert(sizeof(SOP2_instruction) == sizeof(Instruction) + 4, "Unexpected padding"); +static_assert(sizeof(SALU_instruction) == sizeof(Instruction) + 4, "Unexpected padding"); /** * Scalar Memory Format: diff --git a/src/amd/compiler/aco_lower_to_hw_instr.cpp b/src/amd/compiler/aco_lower_to_hw_instr.cpp index 18554e9dfc9..7d63bab1c1e 100644 --- a/src/amd/compiler/aco_lower_to_hw_instr.cpp +++ b/src/amd/compiler/aco_lower_to_hw_instr.cpp @@ -2895,7 +2895,7 @@ lower_to_hw_instr(Program* program) bool is_break_continue = program->blocks[i].kind & (block_kind_break | block_kind_continue); bool discard_early_exit = - program->blocks[inst->sopp().imm].kind & block_kind_discard_early_exit; + program->blocks[inst->salu().imm].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)) diff --git a/src/amd/compiler/aco_opcodes.py b/src/amd/compiler/aco_opcodes.py index 0e736513f0c..005aede671a 100644 --- a/src/amd/compiler/aco_opcodes.py +++ b/src/amd/compiler/aco_opcodes.py @@ -104,7 +104,7 @@ class Format(IntEnum): def get_builder_fields(self): if self == Format.SOPK: - return [('uint16_t', 'imm', None)] + return [('uint32_t', 'imm', '0')] elif self == Format.SOPP: return [('uint32_t', 'imm', '0')] elif self == Format.SMEM: diff --git a/src/amd/compiler/aco_opt_value_numbering.cpp b/src/amd/compiler/aco_opt_value_numbering.cpp index dced78a3729..7183bfcca44 100644 --- a/src/amd/compiler/aco_opt_value_numbering.cpp +++ b/src/amd/compiler/aco_opt_value_numbering.cpp @@ -103,8 +103,8 @@ struct InstrHash { case Format::SMEM: return hash_murmur_32(instr); case Format::VINTRP: return hash_murmur_32(instr); case Format::DS: return hash_murmur_32(instr); - case Format::SOPP: return hash_murmur_32(instr); - case Format::SOPK: return hash_murmur_32(instr); + case Format::SOPP: return hash_murmur_32(instr); + case Format::SOPK: return hash_murmur_32(instr); case Format::EXP: return hash_murmur_32(instr); case Format::MUBUF: return hash_murmur_32(instr); case Format::MIMG: return hash_murmur_32(instr); @@ -209,8 +209,8 @@ struct InstrPred { case Format::SOPK: { if (a->opcode == aco_opcode::s_getreg_b32) return false; - SOPK_instruction& aK = a->sopk(); - SOPK_instruction& bK = b->sopk(); + SALU_instruction& aK = a->salu(); + SALU_instruction& bK = b->salu(); return aK.imm == bK.imm; } case Format::SMEM: { diff --git a/src/amd/compiler/aco_optimizer.cpp b/src/amd/compiler/aco_optimizer.cpp index 2d3cb4b4a25..59f134f976c 100644 --- a/src/amd/compiler/aco_optimizer.cpp +++ b/src/amd/compiler/aco_optimizer.cpp @@ -2468,7 +2468,7 @@ optimize_cmp_subgroup_invocation(opt_ctx& ctx, aco_ptr& instr) const uint64_t mask = BITFIELD64_RANGE(first_bit, num_bits); if (wave_size == 64 && mask > 0x7fffffff && mask != -1ull) { /* Mask can't be represented as a 64-bit constant or literal, use s_bfm_b64. */ - cpy = create_instruction(aco_opcode::s_bfm_b64, Format::SOP2, 2, 1); + cpy = create_instruction(aco_opcode::s_bfm_b64, Format::SOP2, 2, 1); cpy->operands[0] = Operand::c32(num_bits); cpy->operands[1] = Operand::c32(first_bit); } else { @@ -5244,10 +5244,8 @@ try_convert_sopc_to_sopk(aco_ptr& instr) return; } - static_assert(sizeof(SOPK_instruction) <= sizeof(SOPC_instruction), - "Invalid direct instruction cast."); instr->format = Format::SOPK; - SOPK_instruction* instr_sopk = &instr->sopk(); + SALU_instruction* instr_sopk = &instr->salu(); instr_sopk->imm = instr_sopk->operands[1].constantValue() & 0xffff; instr_sopk->opcode = sopk_opcode_for_sopc(instr_sopk->opcode); diff --git a/src/amd/compiler/aco_optimizer_postRA.cpp b/src/amd/compiler/aco_optimizer_postRA.cpp index 5a5cd293283..8b3f83ef1c4 100644 --- a/src/amd/compiler/aco_optimizer_postRA.cpp +++ b/src/amd/compiler/aco_optimizer_postRA.cpp @@ -412,10 +412,10 @@ try_optimize_scc_nocompare(pr_opt_ctx& ctx, aco_ptr& instr) * This means that the original instruction will be eliminated. */ if (wr_instr->format == Format::SOP2) { - instr.reset(create_instruction(pulled_opcode, Format::SOP2, 2, 2)); + instr.reset(create_instruction(pulled_opcode, Format::SOP2, 2, 2)); instr->operands[1] = wr_instr->operands[1]; } else if (wr_instr->format == Format::SOP1) { - instr.reset(create_instruction(pulled_opcode, Format::SOP1, 1, 2)); + instr.reset(create_instruction(pulled_opcode, Format::SOP1, 1, 2)); } instr->definitions[0] = wr_instr->definitions[0]; instr->definitions[1] = scc_def; @@ -526,7 +526,7 @@ try_eliminate_scc_copy(pr_opt_ctx& ctx, aco_ptr& instr) Idx producer_idx = {wr_idx.block, wr_instr->pass_flags}; Instruction* producer_instr = ctx.get(producer_idx); - if (!producer_instr) + if (!producer_instr || !producer_instr->isSALU()) return; /* Verify that the operands of the producer instruction haven't been overwritten. */ @@ -544,20 +544,10 @@ try_eliminate_scc_copy(pr_opt_ctx& ctx, aco_ptr& instr) } /* Duplicate the original producer of the SCC */ - if (producer_instr->isSOP1()) - instr.reset(create_instruction(producer_instr->opcode, Format::SOP1, - producer_instr->operands.size(), - producer_instr->definitions.size())); - else if (producer_instr->isSOP2()) - instr.reset(create_instruction(producer_instr->opcode, Format::SOP2, - producer_instr->operands.size(), - producer_instr->definitions.size())); - else if (producer_instr->isSOPC()) - instr.reset(create_instruction(producer_instr->opcode, Format::SOPC, - producer_instr->operands.size(), - producer_instr->definitions.size())); - else - return; + instr.reset(create_instruction(producer_instr->opcode, producer_instr->format, + producer_instr->operands.size(), + producer_instr->definitions.size())); + instr->salu().imm = producer_instr->salu().imm; /* The copy is no longer needed. */ if (--ctx.uses[wr_instr->definitions[0].tempId()] == 0) diff --git a/src/amd/compiler/aco_print_ir.cpp b/src/amd/compiler/aco_print_ir.cpp index 2fe73672ee5..f4e5014d924 100644 --- a/src/amd/compiler/aco_print_ir.cpp +++ b/src/amd/compiler/aco_print_ir.cpp @@ -285,12 +285,12 @@ print_instr_format_specific(enum amd_gfx_level gfx_level, const Instruction* ins { switch (instr->format) { case Format::SOPK: { - const SOPK_instruction& sopk = instr->sopk(); + const SALU_instruction& sopk = instr->salu(); fprintf(output, " imm:%d", sopk.imm & 0x8000 ? (sopk.imm - 65536) : sopk.imm); break; } case Format::SOPP: { - uint16_t imm = instr->sopp().imm; + uint16_t imm = instr->salu().imm; switch (instr->opcode) { case aco_opcode::s_waitcnt: { wait_imm unpacked(gfx_level, imm); @@ -400,7 +400,7 @@ print_instr_format_specific(enum amd_gfx_level gfx_level, const Instruction* ins } default: { if (instr_info.classes[(int)instr->opcode] == instr_class::branch) - fprintf(output, " block:BB%d", instr->sopp().imm); + fprintf(output, " block:BB%d", imm); else if (imm) fprintf(output, " imm:%u", imm); break; diff --git a/src/amd/compiler/aco_register_allocation.cpp b/src/amd/compiler/aco_register_allocation.cpp index 84ba242ff86..697a226e5bf 100644 --- a/src/amd/compiler/aco_register_allocation.cpp +++ b/src/amd/compiler/aco_register_allocation.cpp @@ -2848,10 +2848,8 @@ optimize_encoding_sopk(Program* program, ra_ctx& ctx, RegisterFile& register_fil return; } - static_assert(sizeof(SOPK_instruction) <= sizeof(SOP2_instruction), - "Invalid direct instruction cast."); instr->format = Format::SOPK; - SOPK_instruction* instr_sopk = &instr->sopk(); + SALU_instruction* instr_sopk = &instr->salu(); instr_sopk->imm = instr_sopk->operands[literal_idx].constantValue() & 0xffff; if (literal_idx == 0) @@ -3319,7 +3317,7 @@ register_allocation(Program* program, live& live_vars, ra_test_policy policy) aco_ptr mov; if (can_sgpr) - mov.reset(create_instruction(aco_opcode::s_mov_b32, + mov.reset(create_instruction(aco_opcode::s_mov_b32, Format::SOP1, 1, 1)); else mov.reset(create_instruction(aco_opcode::v_mov_b32, diff --git a/src/amd/compiler/aco_scheduler.cpp b/src/amd/compiler/aco_scheduler.cpp index b3302dfb715..c5f57e8ce57 100644 --- a/src/amd/compiler/aco_scheduler.cpp +++ b/src/amd/compiler/aco_scheduler.cpp @@ -424,7 +424,7 @@ bool is_done_sendmsg(amd_gfx_level gfx_level, const Instruction* instr) { if (gfx_level <= GFX10_3 && instr->opcode == aco_opcode::s_sendmsg) - return (instr->sopp().imm & sendmsg_id_mask) == sendmsg_gs_done; + return (instr->salu().imm & sendmsg_id_mask) == sendmsg_gs_done; return false; } @@ -577,7 +577,7 @@ perform_hazard_query(hazard_query* query, Instruction* instr, bool upwards) if (upwards) { if (instr->opcode == aco_opcode::p_pops_gfx9_add_exiting_wave_id || (instr->opcode == aco_opcode::s_wait_event && - !(instr->sopp().imm & wait_event_imm_dont_wait_export_ready))) { + !(instr->salu().imm & wait_event_imm_dont_wait_export_ready))) { return hazard_fail_unreorderable; } } else { diff --git a/src/amd/compiler/aco_spill.cpp b/src/amd/compiler/aco_spill.cpp index 92304dfacaf..35a4b6d435d 100644 --- a/src/amd/compiler/aco_spill.cpp +++ b/src/amd/compiler/aco_spill.cpp @@ -355,15 +355,15 @@ do_reload(spill_ctx& ctx, Temp tmp, Temp new_name, uint32_t spill_id) res.reset(create_instruction( instr->opcode, instr->format, instr->operands.size(), instr->definitions.size())); } else if (instr->isSOP1()) { - res.reset(create_instruction( + res.reset(create_instruction( instr->opcode, instr->format, instr->operands.size(), instr->definitions.size())); } else if (instr->isPseudo()) { res.reset(create_instruction( instr->opcode, instr->format, instr->operands.size(), instr->definitions.size())); } else if (instr->isSOPK()) { - res.reset(create_instruction( + res.reset(create_instruction( instr->opcode, instr->format, instr->operands.size(), instr->definitions.size())); - res->sopk().imm = instr->sopk().imm; + res->salu().imm = instr->salu().imm; } for (unsigned i = 0; i < instr->operands.size(); i++) { res->operands[i] = instr->operands[i]; diff --git a/src/amd/compiler/aco_statistics.cpp b/src/amd/compiler/aco_statistics.cpp index 30f3184eff7..117fd13133a 100644 --- a/src/amd/compiler/aco_statistics.cpp +++ b/src/amd/compiler/aco_statistics.cpp @@ -350,9 +350,9 @@ get_wait_imm(Program* program, aco_ptr& instr) if (instr->opcode == aco_opcode::s_endpgm) { return wait_imm(0, 0, 0, 0); } else if (instr->opcode == aco_opcode::s_waitcnt) { - return wait_imm(GFX10_3, instr->sopp().imm); + return wait_imm(GFX10_3, instr->salu().imm); } else if (instr->opcode == aco_opcode::s_waitcnt_vscnt) { - return wait_imm(0, 0, 0, instr->sopk().imm); + return wait_imm(0, 0, 0, instr->salu().imm); } else { unsigned max_lgkm_cnt = program->gfx_level >= GFX10 ? 62 : 14; unsigned max_exp_cnt = 6;