From 1d245cd18b637484512f275b9bb49f05105ad373 Mon Sep 17 00:00:00 2001 From: Rhys Perry Date: Wed, 20 Jan 2021 15:27:16 +0000 Subject: [PATCH] aco: use format-check methods MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rhys Perry Reviewed-by: Daniel Schürmann Part-of: --- src/amd/compiler/aco_assembler.cpp | 22 +++++----- src/amd/compiler/aco_dead_code_analysis.cpp | 2 +- src/amd/compiler/aco_form_hard_clauses.cpp | 6 +-- src/amd/compiler/aco_insert_NOPs.cpp | 43 ++++++++++---------- src/amd/compiler/aco_insert_exec_mask.cpp | 14 +++---- src/amd/compiler/aco_insert_waitcnt.cpp | 14 +++---- src/amd/compiler/aco_ir.cpp | 8 ++-- src/amd/compiler/aco_ir.h | 23 ++--------- src/amd/compiler/aco_lower_phis.cpp | 2 +- src/amd/compiler/aco_lower_to_cssa.cpp | 2 +- src/amd/compiler/aco_lower_to_hw_instr.cpp | 10 ++--- src/amd/compiler/aco_opt_value_numbering.cpp | 2 +- src/amd/compiler/aco_optimizer.cpp | 38 ++++++++--------- src/amd/compiler/aco_print_ir.cpp | 6 +-- src/amd/compiler/aco_register_allocation.cpp | 22 +++++----- src/amd/compiler/aco_scheduler.cpp | 22 +++++----- src/amd/compiler/aco_spill.cpp | 14 +++---- src/amd/compiler/aco_ssa_elimination.cpp | 4 +- src/amd/compiler/aco_statistics.cpp | 4 +- src/amd/compiler/aco_validate.cpp | 38 ++++++++--------- 20 files changed, 137 insertions(+), 159 deletions(-) diff --git a/src/amd/compiler/aco_assembler.cpp b/src/amd/compiler/aco_assembler.cpp index eab84578c72..c4475165aed 100644 --- a/src/amd/compiler/aco_assembler.cpp +++ b/src/amd/compiler/aco_assembler.cpp @@ -493,7 +493,7 @@ void emit_instruction(asm_context& ctx, std::vector& out, Instruction* if (ctx.chip_class <= GFX9) { assert(flat->offset <= 0x1fff); encoding |= flat->offset & 0x1fff; - } else if (instr->format == Format::FLAT) { + } else if (instr->isFlat()) { /* GFX10 has a 12-bit immediate OFFSET field, * but it has a hw bug: it ignores the offset, called FlatSegmentOffsetBug */ @@ -502,9 +502,9 @@ void emit_instruction(asm_context& ctx, std::vector& out, Instruction* assert(flat->offset <= 0xfff); encoding |= flat->offset & 0xfff; } - if (instr->format == Format::SCRATCH) + if (instr->isScratch()) encoding |= 1 << 14; - else if (instr->format == Format::GLOBAL) + else if (instr->isGlobal()) encoding |= 2 << 14; encoding |= flat->lds ? 1 << 13 : 0; encoding |= flat->glc ? 1 << 16 : 0; @@ -563,19 +563,19 @@ void emit_instruction(asm_context& ctx, std::vector& out, Instruction* unreachable("Pseudo instructions should be lowered before assembly."); break; default: - if ((uint16_t) instr->format & (uint16_t) Format::VOP3) { + if (instr->isVOP3()) { VOP3_instruction* vop3 = instr->vop3(); - if ((uint16_t) instr->format & (uint16_t) Format::VOP2) { + if (instr->isVOP2()) { opcode = opcode + 0x100; - } else if ((uint16_t) instr->format & (uint16_t) Format::VOP1) { + } else if (instr->isVOP1()) { if (ctx.chip_class == GFX8 || ctx.chip_class == GFX9) opcode = opcode + 0x140; else opcode = opcode + 0x180; - } else if ((uint16_t) instr->format & (uint16_t) Format::VOPC) { + } else if (instr->isVOPC()) { opcode = opcode + 0x0; - } else if ((uint16_t) instr->format & (uint16_t) Format::VINTRP) { + } else if (instr->isVINTRP()) { opcode = opcode + 0x270; } @@ -614,7 +614,7 @@ void emit_instruction(asm_context& ctx, std::vector& out, Instruction* encoding |= vop3->neg[i] << (29+i); out.push_back(encoding); - } else if (instr->format == Format::VOP3P) { + } else if (instr->isVOP3P()) { VOP3P_instruction* vop3 = instr->vop3p(); uint32_t encoding; @@ -675,7 +675,7 @@ void emit_instruction(asm_context& ctx, std::vector& out, Instruction* uint32_t encoding = 0; - if ((uint16_t)instr->format & (uint16_t)Format::VOPC) { + if (instr->isVOPC()) { if (instr->definitions[0].physReg() != vcc) { encoding |= instr->definitions[0].physReg() << 8; encoding |= 1 << 15; @@ -749,7 +749,7 @@ void fix_exports(asm_context& ctx, std::vector& out, Program* program) std::vector>::reverse_iterator it = block.instructions.rbegin(); while ( it != block.instructions.rend()) { - if ((*it)->format == Format::EXP) { + if ((*it)->isEXP()) { Export_instruction* exp = (*it)->exp(); if (program->stage.hw == HWStage::VS || program->stage.hw == HWStage::NGG) { if (exp->dest >= V_008DFC_SQ_EXP_POS && exp->dest <= (V_008DFC_SQ_EXP_POS + 3)) { diff --git a/src/amd/compiler/aco_dead_code_analysis.cpp b/src/amd/compiler/aco_dead_code_analysis.cpp index b77a3dd89b2..b6203d5070b 100644 --- a/src/amd/compiler/aco_dead_code_analysis.cpp +++ b/src/amd/compiler/aco_dead_code_analysis.cpp @@ -79,7 +79,7 @@ void process_block(dce_ctx& ctx, Block& block) bool is_dead(const std::vector& uses, Instruction *instr) { - if (instr->definitions.empty() || instr->format == Format::PSEUDO_BRANCH) + if (instr->definitions.empty() || instr->isBranch()) return false; if (std::any_of(instr->definitions.begin(), instr->definitions.end(), [&uses] (const Definition& def) { return uses[def.tempId()];})) diff --git a/src/amd/compiler/aco_form_hard_clauses.cpp b/src/amd/compiler/aco_form_hard_clauses.cpp index 950413589c9..e04895a238c 100644 --- a/src/amd/compiler/aco_form_hard_clauses.cpp +++ b/src/amd/compiler/aco_form_hard_clauses.cpp @@ -78,11 +78,11 @@ void form_hard_clauses(Program *program) if (instr->isVMEM() && !instr->operands.empty()) { resource = instr->operands[0].tempId(); type = clause_vmem; - } else if (instr->format == Format::SCRATCH || instr->format == Format::GLOBAL) { + } else if (instr->isScratch() || instr->isGlobal()) { type = clause_vmem; - } else if (instr->format == Format::FLAT) { + } else if (instr->isFlat()) { type = clause_flat; - } else if (instr->format == Format::SMEM && !instr->operands.empty()) { + } else if (instr->isSMEM() && !instr->operands.empty()) { type = clause_smem; if (instr->operands[0].bytes() == 16) resource = instr->operands[0].tempId(); diff --git a/src/amd/compiler/aco_insert_NOPs.cpp b/src/amd/compiler/aco_insert_NOPs.cpp index a5df7bfac42..5c59e6ab68c 100644 --- a/src/amd/compiler/aco_insert_NOPs.cpp +++ b/src/amd/compiler/aco_insert_NOPs.cpp @@ -213,7 +213,7 @@ int handle_raw_hazard_internal(Program *program, Block *block, bool is_hazard = writemask != 0 && ((pred->isVALU() && Valu) || - (pred->format == Format::VINTRP && Vintrp) || + (pred->isVINTRP() && Vintrp) || (pred->isSALU() && Salu)); if (is_hazard) return nops_needed; @@ -316,7 +316,7 @@ void handle_instruction_gfx6(Program *program, Block *cur_block, NOP_ctx_gfx6 &c /* check hazards */ int NOPs = 0; - if (instr->format == Format::SMEM) { + if (instr->isSMEM()) { if (program->chip_class == GFX6) { /* A read of an SGPR by SMRD instruction requires 4 wait states * when the SGPR was written by a VALU instruction. According to LLVM, @@ -351,9 +351,9 @@ void handle_instruction_gfx6(Program *program, Block *cur_block, NOP_ctx_gfx6 &c if (instr->opcode == aco_opcode::s_sendmsg || instr->opcode == aco_opcode::s_ttracedata) NOPs = MAX2(NOPs, ctx.salu_wr_m0_then_gds_msg_ttrace); - } else if (instr->format == Format::DS && instr->ds()->gds) { + } else if (instr->isDS() && instr->ds()->gds) { NOPs = MAX2(NOPs, ctx.salu_wr_m0_then_gds_msg_ttrace); - } else if (instr->isVALU() || instr->format == Format::VINTRP) { + } else if (instr->isVALU() || instr->isVINTRP()) { for (Operand op : instr->operands) { if (op.physReg() == vccz) NOPs = MAX2(NOPs, ctx.valu_wr_vcc_then_vccz); @@ -394,7 +394,7 @@ void handle_instruction_gfx6(Program *program, Block *cur_block, NOP_ctx_gfx6 &c if (instr->opcode == aco_opcode::v_div_fmas_f32 || instr->opcode == aco_opcode::v_div_fmas_f64) NOPs = MAX2(NOPs, ctx.valu_wr_vcc_then_div_fmas); - } else if (instr->isVMEM() || instr->isFlatOrGlobal() || instr->format == Format::SCRATCH) { + } else if (instr->isVMEM() || instr->isFlatLike()) { /* If the VALU writes the SGPR that is used by a VMEM, the user must add five wait states. */ for (Operand op : instr->operands) { if (!op.isConstant() && !op.isUndefined() && op.regClass().type() == RegType::sgpr) @@ -406,9 +406,9 @@ void handle_instruction_gfx6(Program *program, Block *cur_block, NOP_ctx_gfx6 &c NOPs = MAX2(NOPs, ctx.set_vskip_mode_then_vector); if (program->chip_class == GFX9) { - bool lds_scratch_global = (instr->format == Format::SCRATCH || instr->format == Format::GLOBAL) && + bool lds_scratch_global = (instr->isScratch() || instr->isGlobal()) && instr->flatlike()->lds; - if (instr->format == Format::VINTRP || + if (instr->isVINTRP() || instr->opcode == aco_opcode::ds_read_addtid_b32 || instr->opcode == aco_opcode::ds_write_addtid_b32 || instr->opcode == aco_opcode::buffer_store_lds_dword || @@ -439,7 +439,7 @@ void handle_instruction_gfx6(Program *program, Block *cur_block, NOP_ctx_gfx6 &c } } - if (instr->format == Format::SMEM) { + if (instr->isSMEM()) { if (instr->definitions.empty() || instr_info.is_atomic[(unsigned)instr->opcode]) { ctx.smem_write = true; } else { @@ -489,21 +489,21 @@ void handle_instruction_gfx6(Program *program, Block *cur_block, NOP_ctx_gfx6 &c if (reg == 1 && offset >= 28 && size > (28 - offset)) ctx.set_vskip_mode_then_vector = 2; } - } else if (instr->isVMEM() || instr->isFlatOrGlobal() || instr->format == Format::SCRATCH) { + } else if (instr->isVMEM() || instr->isFlatLike()) { /* >64-bit MUBUF/MTBUF store with a constant in SOFFSET */ - bool consider_buf = (instr->format == Format::MUBUF || instr->format == Format::MTBUF) && + bool consider_buf = (instr->isMUBUF() || instr->isMTBUF()) && instr->operands.size() == 4 && instr->operands[3].size() > 2 && instr->operands[2].physReg() >= 128; /* MIMG store with a 128-bit T# with more than two bits set in dmask (making it a >64-bit store) */ - bool consider_mimg = instr->format == Format::MIMG && + bool consider_mimg = instr->isMIMG() && instr->operands[1].regClass().type() == RegType::vgpr && instr->operands[1].size() > 2 && instr->operands[0].size() == 4; /* FLAT/GLOBAL/SCRATCH store with >64-bit data */ - bool consider_flat = (instr->isFlatOrGlobal() || instr->format == Format::SCRATCH) && - instr->operands.size() == 3 && - instr->operands[2].size() > 2; + bool consider_flat = instr->isFlatLike() && + instr->operands.size() == 3 && + instr->operands[2].size() > 2; if (consider_buf || consider_mimg || consider_flat) { PhysReg wrdata = instr->operands[consider_flat ? 2 : 3].physReg(); unsigned size = instr->operands[consider_flat ? 2 : 3].size(); @@ -540,7 +540,7 @@ void mark_read_regs(const aco_ptr &instr, std::bitset ®_reads bool VALU_writes_sgpr(aco_ptr& instr) { - if ((uint32_t) instr->format & (uint32_t) Format::VOPC) + if (instr->isVOPC()) return true; if (instr->isVOP3() && instr->definitions.size() == 2) return true; @@ -594,14 +594,13 @@ void handle_instruction_gfx10(Program *program, Block *cur_block, NOP_ctx_gfx10 /* VMEMtoScalarWriteHazard * Handle EXEC/M0/SGPR write following a VMEM instruction without a VALU or "waitcnt vmcnt(0)" in-between. */ - if (instr->isVMEM() || instr->format == Format::FLAT || instr->format == Format::GLOBAL || - instr->format == Format::SCRATCH || instr->format == Format::DS) { + if (instr->isVMEM() || instr->isFlatLike() || instr->isDS()) { /* Remember all SGPRs that are read by the VMEM instruction */ mark_read_regs(instr, ctx.sgprs_read_by_VMEM); ctx.sgprs_read_by_VMEM.set(exec); if (program->wave_size == 64) ctx.sgprs_read_by_VMEM.set(exec_hi); - } else if (instr->isSALU() || instr->format == Format::SMEM) { + } else if (instr->isSALU() || instr->isSMEM()) { if (instr->opcode == aco_opcode::s_waitcnt) { /* Hazard is mitigated by "s_waitcnt vmcnt(0)" */ uint16_t imm = instr->sopp()->imm; @@ -632,7 +631,7 @@ void handle_instruction_gfx10(Program *program, Block *cur_block, NOP_ctx_gfx10 /* VcmpxPermlaneHazard * Handle any permlane following a VOPC instruction, insert v_mov between them. */ - if (instr->format == Format::VOPC) { + if (instr->isVOPC()) { ctx.has_VOPC = true; } else if (ctx.has_VOPC && (instr->opcode == aco_opcode::v_permlane16_b32 || @@ -675,7 +674,7 @@ void handle_instruction_gfx10(Program *program, Block *cur_block, NOP_ctx_gfx10 /* SMEMtoVectorWriteHazard * Handle any VALU instruction writing an SGPR after an SMEM reads it. */ - if (instr->format == Format::SMEM) { + if (instr->isSMEM()) { /* Remember all SGPRs that are read by the SMEM instruction */ mark_read_regs(instr, ctx.sgprs_read_by_SMEM); } else if (VALU_writes_sgpr(instr)) { @@ -710,12 +709,12 @@ void handle_instruction_gfx10(Program *program, Block *cur_block, NOP_ctx_gfx10 /* LdsBranchVmemWARHazard * Handle VMEM/GLOBAL/SCRATCH->branch->DS and DS->branch->VMEM/GLOBAL/SCRATCH patterns. */ - if (instr->isVMEM() || instr->format == Format::GLOBAL || instr->format == Format::SCRATCH) { + if (instr->isVMEM() || instr->isGlobal() || instr->isScratch()) { ctx.has_VMEM = true; ctx.has_branch_after_VMEM = false; /* Mitigation for DS is needed only if there was already a branch after */ ctx.has_DS = ctx.has_branch_after_DS; - } else if (instr->format == Format::DS) { + } else if (instr->isDS()) { ctx.has_DS = true; ctx.has_branch_after_DS = false; /* Mitigation for VMEM is needed only if there was already a branch after */ diff --git a/src/amd/compiler/aco_insert_exec_mask.cpp b/src/amd/compiler/aco_insert_exec_mask.cpp index 33d7a5a8096..d5153a105c6 100644 --- a/src/amd/compiler/aco_insert_exec_mask.cpp +++ b/src/amd/compiler/aco_insert_exec_mask.cpp @@ -97,16 +97,16 @@ struct exec_ctx { }; bool needs_exact(aco_ptr& instr) { - if (instr->format == Format::MUBUF) { + if (instr->isMUBUF()) { return instr->mubuf()->disable_wqm; - } else if (instr->format == Format::MTBUF) { + } else if (instr->isMTBUF()) { return instr->mtbuf()->disable_wqm; - } else if (instr->format == Format::MIMG) { + } else if (instr->isMIMG()) { return instr->mimg()->disable_wqm; - } else if (instr->format == Format::FLAT || instr->format == Format::GLOBAL) { + } else if (instr->isFlatLike()) { return instr->flatlike()->disable_wqm; } else { - return instr->format == Format::EXP; + return instr->isEXP(); } } @@ -190,7 +190,7 @@ void get_block_needs(wqm_ctx &ctx, exec_ctx &exec_ctx, Block* block) } } - if (instr->format == Format::PSEUDO_BRANCH && ctx.branch_wqm[block->index]) { + if (instr->isBranch() && ctx.branch_wqm[block->index]) { needs = WQM; propagate_wqm = true; } @@ -854,7 +854,7 @@ void add_branch_code(exec_ctx& ctx, Block* block) if (block->kind & block_kind_discard) { - assert(block->instructions.back()->format == Format::PSEUDO_BRANCH); + assert(block->instructions.back()->isBranch()); aco_ptr branch = std::move(block->instructions.back()); block->instructions.pop_back(); diff --git a/src/amd/compiler/aco_insert_waitcnt.cpp b/src/amd/compiler/aco_insert_waitcnt.cpp index 2f23fe2949e..2c5c115124e 100644 --- a/src/amd/compiler/aco_insert_waitcnt.cpp +++ b/src/amd/compiler/aco_insert_waitcnt.cpp @@ -416,16 +416,14 @@ wait_imm check_instr(Instruction* instr, wait_ctx& ctx) continue; /* Vector Memory reads and writes return in the order they were issued */ - bool has_sampler = instr->format == Format::MIMG && !instr->operands[1].isUndefined() && instr->operands[1].regClass() == s4; + bool has_sampler = instr->isMIMG() && !instr->operands[1].isUndefined() && instr->operands[1].regClass() == s4; if (instr->isVMEM() && ((it->second.events & vm_events) == event_vmem) && it->second.has_vmem_nosampler == !has_sampler && it->second.has_vmem_sampler == has_sampler) continue; /* LDS reads and writes return in the order they were issued. same for GDS */ - if (instr->format == Format::DS) { - if ((it->second.events & lgkm_events) == (instr->ds()->gds ? event_gds : event_lds)) - continue; - } + if (instr->isDS() && (it->second.events & lgkm_events) == (instr->ds()->gds ? event_gds : event_lds)) + continue; wait.combine(it->second.imm); } @@ -515,7 +513,7 @@ wait_imm kill(Instruction* instr, wait_ctx& ctx, memory_sync_info sync_info) imm.lgkm = 0; } - if (ctx.chip_class >= GFX10 && instr->format == Format::SMEM) { + if (ctx.chip_class >= GFX10 && instr->isSMEM()) { /* GFX10: A store followed by a load at the same address causes a problem because * the load doesn't load the correct values unless we wait for the store first. * This is NOT mitigated by an s_nop. @@ -832,7 +830,7 @@ void gen(Instruction* instr, wait_ctx& ctx) wait_event ev = !instr->definitions.empty() || ctx.chip_class < GFX10 ? event_vmem : event_vmem_store; update_counters(ctx, ev, get_sync_info(instr)); - bool has_sampler = instr->format == Format::MIMG && !instr->operands[1].isUndefined() && instr->operands[1].regClass() == s4; + bool has_sampler = instr->isMIMG() && !instr->operands[1].isUndefined() && instr->operands[1].regClass() == s4; if (!instr->definitions.empty()) insert_wait_entry(ctx, instr->definitions[0], ev, has_sampler); @@ -844,7 +842,7 @@ void gen(Instruction* instr, wait_ctx& ctx) update_counters(ctx, event_vmem_gpr_lock); insert_wait_entry(ctx, instr->operands[3], event_vmem_gpr_lock); } else if (ctx.chip_class == GFX6 && - instr->format == Format::MIMG && + instr->isMIMG() && !instr->operands[2].isUndefined()) { ctx.exp_cnt++; update_counters(ctx, event_vmem_gpr_lock); diff --git a/src/amd/compiler/aco_ir.cpp b/src/amd/compiler/aco_ir.cpp index 816edffa01f..ed3a43a2234 100644 --- a/src/amd/compiler/aco_ir.cpp +++ b/src/amd/compiler/aco_ir.cpp @@ -206,7 +206,7 @@ bool can_use_SDWA(chip_class chip, const aco_ptr& instr) return false; //TODO: return true if we know we will use vcc - if ((unsigned)instr->format & (unsigned)Format::VOPC) + if (instr->isVOPC()) return false; if (instr->operands.size() >= 3 && !is_mac) return false; @@ -411,12 +411,12 @@ uint32_t get_reduction_identity(ReduceOp op, unsigned idx) bool needs_exec_mask(const Instruction* instr) { if (instr->isSALU()) return instr->reads_exec(); - if (instr->format == Format::SMEM || instr->isSALU()) + if (instr->isSMEM() || instr->isSALU()) return false; - if (instr->format == Format::PSEUDO_BARRIER) + if (instr->isBarrier()) return false; - if (instr->format == Format::PSEUDO) { + if (instr->isPseudo()) { switch (instr->opcode) { case aco_opcode::p_create_vector: case aco_opcode::p_extract_vector: diff --git a/src/amd/compiler/aco_ir.h b/src/amd/compiler/aco_ir.h index caa0d840aab..62e4f0d7c52 100644 --- a/src/amd/compiler/aco_ir.h +++ b/src/amd/compiler/aco_ir.h @@ -1126,32 +1126,17 @@ struct Instruction { constexpr bool isVALU() const noexcept { - return ((uint16_t) format & (uint16_t) Format::VOP1) == (uint16_t) Format::VOP1 - || ((uint16_t) format & (uint16_t) Format::VOP2) == (uint16_t) Format::VOP2 - || ((uint16_t) format & (uint16_t) Format::VOPC) == (uint16_t) Format::VOPC - || ((uint16_t) format & (uint16_t) Format::VOP3) == (uint16_t) Format::VOP3 - || format == Format::VOP3P; + return isVOP1() || isVOP2() || isVOPC() || isVOP3() || isVOP3P(); } constexpr bool isSALU() const noexcept { - return format == Format::SOP1 || - format == Format::SOP2 || - format == Format::SOPC || - format == Format::SOPK || - format == Format::SOPP; + return isSOP1() || isSOP2() || isSOPC() || isSOPK() || isSOPP(); } constexpr bool isVMEM() const noexcept { - return format == Format::MTBUF || - format == Format::MUBUF || - format == Format::MIMG; - } - - constexpr bool isFlatOrGlobal() const noexcept - { - return format == Format::FLAT || format == Format::GLOBAL; + return isMTBUF() || isMUBUF() || isMIMG(); } }; static_assert(sizeof(Instruction) == 16, "Unexpected padding"); @@ -1538,7 +1523,7 @@ constexpr bool Instruction::usesModifiers() const noexcept if (isDPP() || isSDWA()) return true; - if (format == Format::VOP3P) { + if (isVOP3P()) { const VOP3P_instruction *vop3p = this->vop3p(); for (unsigned i = 0; i < operands.size(); i++) { if (vop3p->neg_lo[i] || vop3p->neg_hi[i]) diff --git a/src/amd/compiler/aco_lower_phis.cpp b/src/amd/compiler/aco_lower_phis.cpp index da703e01bd6..07fad653ba4 100644 --- a/src/amd/compiler/aco_lower_phis.cpp +++ b/src/amd/compiler/aco_lower_phis.cpp @@ -109,7 +109,7 @@ void insert_before_logical_end(Block *block, aco_ptr instr) auto it = std::find_if(block->instructions.crbegin(), block->instructions.crend(), IsLogicalEnd); if (it == block->instructions.crend()) { - assert(block->instructions.back()->format == Format::PSEUDO_BRANCH); + assert(block->instructions.back()->isBranch()); block->instructions.insert(std::prev(block->instructions.end()), std::move(instr)); } else { block->instructions.insert(std::prev(it.base()), std::move(instr)); diff --git a/src/amd/compiler/aco_lower_to_cssa.cpp b/src/amd/compiler/aco_lower_to_cssa.cpp index f64ac68f962..4dba8aa2677 100644 --- a/src/amd/compiler/aco_lower_to_cssa.cpp +++ b/src/amd/compiler/aco_lower_to_cssa.cpp @@ -180,7 +180,7 @@ void insert_parallelcopies(cssa_ctx& ctx) Block& block = ctx.program->blocks[entry.first]; std::vector>::iterator it = block.instructions.end(); --it; - assert((*it)->format == Format::PSEUDO_BRANCH); + assert((*it)->isBranch()); Builder bld(ctx.program); bld.reset(&block.instructions, it); diff --git a/src/amd/compiler/aco_lower_to_hw_instr.cpp b/src/amd/compiler/aco_lower_to_hw_instr.cpp index 1ebca2b9243..180b38ebfbf 100644 --- a/src/amd/compiler/aco_lower_to_hw_instr.cpp +++ b/src/amd/compiler/aco_lower_to_hw_instr.cpp @@ -1809,7 +1809,7 @@ void lower_to_hw_instr(Program* program) for (size_t instr_idx = 0; instr_idx < block->instructions.size(); instr_idx++) { aco_ptr& instr = block->instructions[instr_idx]; aco_ptr mov; - if (instr->format == Format::PSEUDO && instr->opcode != aco_opcode::p_unit_test) { + if (instr->isPseudo() && instr->opcode != aco_opcode::p_unit_test) { Pseudo_instruction *pi = instr->pseudo(); switch (instr->opcode) @@ -1982,7 +1982,7 @@ void lower_to_hw_instr(Program* program) default: break; } - } else if (instr->format == Format::PSEUDO_BRANCH) { + } else if (instr->isBranch()) { Pseudo_branch_instruction* branch = instr->branch(); uint32_t target = branch->target[0]; @@ -2002,7 +2002,7 @@ void lower_to_hw_instr(Program* program) } for (aco_ptr& inst : program->blocks[i].instructions) { - if (inst->format == Format::SOPP) { + if (inst->isSOPP()) { can_remove = false; } else if (inst->isSALU()) { num_scalar++; @@ -2054,7 +2054,7 @@ void lower_to_hw_instr(Program* program) unreachable("Unknown Pseudo branch instruction!"); } - } else if (instr->format == Format::PSEUDO_REDUCTION) { + } else if (instr->isReduction()) { Pseudo_reduction_instruction* reduce = instr->reduction(); emit_reduction(&ctx, reduce->opcode, reduce->reduce_op, reduce->cluster_size, reduce->operands[1].physReg(), // tmp @@ -2062,7 +2062,7 @@ void lower_to_hw_instr(Program* program) reduce->operands[2].physReg(), // vtmp reduce->definitions[2].physReg(), // sitmp reduce->operands[0], reduce->definitions[0]); - } else if (instr->format == Format::PSEUDO_BARRIER) { + } else if (instr->isBarrier()) { Pseudo_barrier_instruction* barrier = instr->barrier(); /* Anything larger than a workgroup isn't possible. Anything diff --git a/src/amd/compiler/aco_opt_value_numbering.cpp b/src/amd/compiler/aco_opt_value_numbering.cpp index 80b09602717..de0eb94befa 100644 --- a/src/amd/compiler/aco_opt_value_numbering.cpp +++ b/src/amd/compiler/aco_opt_value_numbering.cpp @@ -174,7 +174,7 @@ struct InstrPred { return a->pass_flags == b->pass_flags; /* The results of VOPC depend on the exec mask if used for subgroup operations. */ - if ((uint32_t) a->format & (uint32_t) Format::VOPC && a->pass_flags != b->pass_flags) + if (a->isVOPC() && a->pass_flags != b->pass_flags) return false; if (a->isVOP3()) { diff --git a/src/amd/compiler/aco_optimizer.cpp b/src/amd/compiler/aco_optimizer.cpp index de45a981171..63bb9b1f16e 100644 --- a/src/amd/compiler/aco_optimizer.cpp +++ b/src/amd/compiler/aco_optimizer.cpp @@ -605,7 +605,7 @@ bool can_use_VOP3(opt_ctx& ctx, const aco_ptr& instr) if (instr->isVOP3()) return true; - if (instr->format == Format::VOP3P) + if (instr->isVOP3P()) return false; if (instr->operands.size() && instr->operands[0].isLiteral() && ctx.program->chip_class < GFX10) @@ -854,7 +854,7 @@ bool parse_base_offset(opt_ctx &ctx, Instruction* instr, unsigned op_index, Temp unsigned get_operand_size(aco_ptr& instr, unsigned index) { - if (instr->format == Format::PSEUDO) + if (instr->isPseudo()) return instr->operands[index].bytes() * 8u; else if (instr->opcode == aco_opcode::v_mad_u64_u32 || instr->opcode == aco_opcode::v_mad_i64_i32) return index == 2 ? 64 : 32; @@ -878,7 +878,7 @@ bool fixed_to_exec(Operand op) void label_instruction(opt_ctx &ctx, Block& block, aco_ptr& instr) { - if (instr->isSALU() || instr->isVALU() || instr->format == Format::PSEUDO) { + if (instr->isSALU() || instr->isVALU() || instr->isPseudo()) { 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)); @@ -906,7 +906,7 @@ void label_instruction(opt_ctx &ctx, Block& block, aco_ptr& instr) } /* PSEUDO: propagate temporaries */ - if (instr->format == Format::PSEUDO) { + if (instr->isPseudo()) { while (info.is_temp()) { pseudo_propagate_temp(ctx, instr, info.temp, i); info = ctx.info[info.temp.id()]; @@ -914,9 +914,9 @@ void label_instruction(opt_ctx &ctx, Block& block, aco_ptr& instr) } /* SALU / PSEUDO: propagate inline constants */ - if (instr->isSALU() || instr->format == Format::PSEUDO) { + if (instr->isSALU() || instr->isPseudo()) { unsigned bits = get_operand_size(instr, i); - if ((info.is_constant(bits) || (info.is_literal(bits) && instr->format == Format::PSEUDO)) && + if ((info.is_constant(bits) || (info.is_literal(bits) && instr->isPseudo())) && !instr->operands[i].isFixed() && alu_can_accept_constant(instr->opcode, i)) { instr->operands[i] = get_constant_op(ctx, info, bits); continue; @@ -980,7 +980,7 @@ void label_instruction(opt_ctx &ctx, Block& block, aco_ptr& instr) (!instr->isSDWA() || ctx.program->chip_class >= GFX9)) { Operand op = get_constant_op(ctx, info, bits); 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->isSDWA() || instr->format == Format::VOP3P || + if (i == 0 || instr->isSDWA() || instr->isVOP3P() || instr->opcode == aco_opcode::v_readlane_b32 || instr->opcode == aco_opcode::v_writelane_b32) { instr->operands[i] = op; @@ -998,7 +998,7 @@ void label_instruction(opt_ctx &ctx, Block& block, aco_ptr& instr) } /* MUBUF: propagate constants and combine additions */ - else if (instr->format == Format::MUBUF) { + else if (instr->isMUBUF()) { MUBUF_instruction *mubuf = instr->mubuf(); Temp base; uint32_t offset; @@ -1039,7 +1039,7 @@ void label_instruction(opt_ctx &ctx, Block& block, aco_ptr& instr) } /* DS: combine additions */ - else if (instr->format == Format::DS) { + else if (instr->isDS()) { DS_instruction *ds = instr->ds(); Temp base; @@ -1071,7 +1071,7 @@ void label_instruction(opt_ctx &ctx, Block& block, aco_ptr& instr) } /* SMEM: propagate constants and combine additions */ - else if (instr->format == Format::SMEM) { + else if (instr->isSMEM()) { SMEM_instruction *smem = instr->smem(); Temp base; @@ -1114,7 +1114,7 @@ void label_instruction(opt_ctx &ctx, Block& block, aco_ptr& instr) } } - else if (instr->format == Format::PSEUDO_BRANCH) { + else if (instr->isBranch()) { if (ctx.info[instr->operands[0].tempId()].is_scc_invert()) { /* Flip the branch instruction to get rid of the scc_invert instruction */ instr->opcode = instr->opcode == aco_opcode::p_cbranch_z ? aco_opcode::p_cbranch_nz : aco_opcode::p_cbranch_z; @@ -1127,11 +1127,11 @@ void label_instruction(opt_ctx &ctx, Block& block, aco_ptr& instr) if (instr->definitions.empty()) return; - if ((uint16_t) instr->format & (uint16_t) Format::VOPC) { + if (instr->isVOPC()) { ctx.info[instr->definitions[0].tempId()].set_vopc(instr.get()); return; } - if (instr->format == Format::VOP3P) { + if (instr->isVOP3P()) { ctx.info[instr->definitions[0].tempId()].set_vop3p(instr.get()); return; } @@ -2567,7 +2567,7 @@ void apply_sgprs(opt_ctx &ctx, aco_ptr& instr) continue; if (sgpr_idx == 0 || instr->isVOP3() || - instr->isSDWA() || instr->format == Format::VOP3P) { + instr->isSDWA() || instr->isVOP3P()) { instr->operands[sgpr_idx] = Operand(sgpr); } else if (can_swap_operands(instr)) { instr->operands[sgpr_idx] = instr->operands[0]; @@ -2873,7 +2873,7 @@ void combine_vop3p(opt_ctx &ctx, Block& block, aco_ptr& instr) } /* turn packed mul+add into v_pk_fma_f16 */ - assert(mul_instr->format == Format::VOP3P); + assert(mul_instr->isVOP3P()); aco_ptr fma{create_instruction(aco_opcode::v_pk_fma_f16, Format::VOP3P, 3, 1)}; VOP3P_instruction* mul = mul_instr->vop3p(); for (unsigned i = 0; i < 2; i++) { @@ -2913,7 +2913,7 @@ void combine_instruction(opt_ctx &ctx, Block& block, aco_ptr& instr while (apply_omod_clamp(ctx, block, instr)) ; } - if (instr->format == Format::VOP3P) + if (instr->isVOP3P()) return combine_vop3p(ctx, block, instr); if (ctx.info[instr->definitions[0].tempId()].is_vcc_hint()) { @@ -3393,7 +3393,7 @@ void select_instruction(opt_ctx &ctx, aco_ptr& instr) } /* Mark SCC needed, so the uniform boolean transformation won't swap the definitions when it isn't beneficial */ - if (instr->format == Format::PSEUDO_BRANCH && + if (instr->isBranch() && instr->operands.size() && instr->operands[0].isTemp() && instr->operands[0].isFixed() && @@ -3440,7 +3440,7 @@ void select_instruction(opt_ctx &ctx, aco_ptr& instr) if (instr->isSDWA() || instr->isDPP() || (instr->isVOP3() && ctx.program->chip_class < GFX10) || - (instr->format == Format::VOP3P && ctx.program->chip_class < GFX10)) + (instr->isVOP3P() && ctx.program->chip_class < GFX10)) return; /* some encodings can't ever take literals */ /* we do not apply the literals yet as we don't know if it is profitable */ @@ -3452,7 +3452,7 @@ void select_instruction(opt_ctx &ctx, aco_ptr& instr) unsigned num_operands = 1; if (instr->isSALU() || (ctx.program->chip_class >= GFX10 && - (can_use_VOP3(ctx, instr) || instr->format == Format::VOP3P))) + (can_use_VOP3(ctx, instr) || instr->isVOP3P()))) num_operands = instr->operands.size(); /* catch VOP2 with a 3rd SGPR operand (e.g. v_cndmask_b32, v_addc_co_u32) */ else if (instr->isVALU() && instr->operands.size() >= 3) diff --git a/src/amd/compiler/aco_print_ir.cpp b/src/amd/compiler/aco_print_ir.cpp index a4e3b8f53ce..16d198f43f8 100644 --- a/src/amd/compiler/aco_print_ir.cpp +++ b/src/amd/compiler/aco_print_ir.cpp @@ -640,7 +640,7 @@ static void print_instr_format_specific(const Instruction *instr, FILE *output) fprintf(output, " bank_mask:0x%.1x", dpp->bank_mask); if (dpp->bound_ctrl) fprintf(output, " bound_ctrl:1"); - } else if ((int)instr->format & (int)Format::SDWA) { + } else if (instr->isSDWA()) { const SDWA_instruction* sdwa = instr->sdwa(); switch (sdwa->omod) { case 1: @@ -692,7 +692,7 @@ void aco_print_instr(const Instruction *instr, FILE *output) bool *const neg = (bool *)alloca(instr->operands.size() * sizeof(bool)); bool *const opsel = (bool *)alloca(instr->operands.size() * sizeof(bool)); uint8_t *const sel = (uint8_t *)alloca(instr->operands.size() * sizeof(uint8_t)); - if ((int)instr->format & (int)Format::VOP3) { + if (instr->isVOP3()) { const VOP3_instruction* vop3 = instr->vop3(); for (unsigned i = 0; i < instr->operands.size(); ++i) { abs[i] = vop3->abs[i]; @@ -755,7 +755,7 @@ void aco_print_instr(const Instruction *instr, FILE *output) if (abs[i]) fprintf(output, "|"); - if (instr->format == Format::VOP3P) { + if (instr->isVOP3P()) { const VOP3P_instruction* vop3 = instr->vop3p(); if ((vop3->opsel_lo & (1 << i)) || !(vop3->opsel_hi & (1 << i))) { fprintf(output, ".%c%c", diff --git a/src/amd/compiler/aco_register_allocation.cpp b/src/amd/compiler/aco_register_allocation.cpp index c6e482fd55b..78089356b20 100644 --- a/src/amd/compiler/aco_register_allocation.cpp +++ b/src/amd/compiler/aco_register_allocation.cpp @@ -427,7 +427,7 @@ unsigned get_subdword_operand_stride(chip_class chip, const aco_ptr /* v_readfirstlane_b32 cannot use SDWA */ if (instr->opcode == aco_opcode::p_as_uniform) return 4; - if (instr->format == Format::PSEUDO && chip >= GFX8) + if (instr->isPseudo() && chip >= GFX8) return rc.bytes() % 2 == 0 ? 2 : 1; if (instr->opcode == aco_opcode::v_cvt_f32_ubyte0) { @@ -436,7 +436,7 @@ unsigned get_subdword_operand_stride(chip_class chip, const aco_ptr return rc.bytes() % 2 == 0 ? 2 : 1; } else if (rc.bytes() == 2 && can_use_opsel(chip, instr->opcode, idx, 1)) { return 2; - } else if (instr->format == Format::VOP3P) { + } else if (instr->isVOP3P()) { return 2; } @@ -476,7 +476,7 @@ void update_phi_map(ra_ctx& ctx, Instruction *old, Instruction *instr) void add_subdword_operand(ra_ctx& ctx, aco_ptr& instr, unsigned idx, unsigned byte, RegClass rc) { chip_class chip = ctx.program->chip_class; - if (instr->format == Format::PSEUDO || byte == 0) + if (instr->isPseudo() || byte == 0) return; assert(rc.bytes() <= 2); @@ -505,7 +505,7 @@ void add_subdword_operand(ra_ctx& ctx, aco_ptr& instr, unsigned idx } else if (rc.bytes() == 2 && can_use_opsel(chip, instr->opcode, idx, byte / 2)) { instr->vop3()->opsel |= (byte / 2) << idx; return; - } else if (instr->format == Format::VOP3P && byte == 2) { + } else if (instr->isVOP3P() && byte == 2) { VOP3P_instruction* vop3p = instr->vop3p(); assert(!(vop3p->opsel_lo & (1 << idx))); vop3p->opsel_lo |= 1 << idx; @@ -549,9 +549,9 @@ std::pair get_subdword_definition_info(Program *program, con { chip_class chip = program->chip_class; - if (instr->format == Format::PSEUDO && chip >= GFX8) + if (instr->isPseudo() && chip >= GFX8) return std::make_pair(rc.bytes() % 2 == 0 ? 2 : 1, rc.bytes()); - else if (instr->format == Format::PSEUDO) + else if (instr->isPseudo()) return std::make_pair(4, rc.size() * 4u); unsigned bytes_written = chip >= GFX10 ? rc.bytes() : 4u; @@ -605,7 +605,7 @@ void add_subdword_definition(Program *program, aco_ptr& instr, unsi RegClass rc = instr->definitions[idx].regClass(); chip_class chip = program->chip_class; - if (instr->format == Format::PSEUDO) { + if (instr->isPseudo()) { return; } else if (can_use_SDWA(chip, instr)) { unsigned def_size = instr_info.definition_size[(int)instr->opcode]; @@ -2154,9 +2154,9 @@ void register_allocation(Program *program, std::vector& live_out_per_bloc else get_reg_for_operand(ctx, register_file, parallelcopy, instr, operand, i); - if (instr->format == Format::EXP || + if (instr->isEXP() || (instr->isVMEM() && i == 3 && ctx.program->chip_class == GFX6) || - (instr->format == Format::DS && instr->ds()->gds)) { + (instr->isDS() && instr->ds()->gds)) { for (unsigned j = 0; j < operand.size(); j++) ctx.war_hint.set(operand.physReg().reg() + j); } @@ -2230,11 +2230,11 @@ void register_allocation(Program *program, std::vector& live_out_per_bloc } else if (instr->opcode == aco_opcode::s_addk_i32 || instr->opcode == aco_opcode::s_mulk_i32) { instr->definitions[0].setFixed(instr->operands[0].physReg()); - } else if (instr->format == Format::MUBUF && + } else if (instr->isMUBUF() && instr->definitions.size() == 1 && instr->operands.size() == 4) { instr->definitions[0].setFixed(instr->operands[3].physReg()); - } else if (instr->format == Format::MIMG && + } else if (instr->isMIMG() && instr->definitions.size() == 1 && !instr->operands[2].isUndefined()) { instr->definitions[0].setFixed(instr->operands[2].physReg()); diff --git a/src/amd/compiler/aco_scheduler.cpp b/src/amd/compiler/aco_scheduler.cpp index 0a979849605..25aee52ec24 100644 --- a/src/amd/compiler/aco_scheduler.cpp +++ b/src/amd/compiler/aco_scheduler.cpp @@ -337,7 +337,7 @@ bool is_done_sendmsg(const Instruction *instr) memory_sync_info get_sync_info_with_hack(const Instruction* instr) { memory_sync_info sync = get_sync_info(instr); - if (instr->format == Format::SMEM && !instr->operands.empty() && instr->operands[0].bytes() == 16) { + if (instr->isSMEM() && !instr->operands.empty() && instr->operands[0].bytes() == 16) { // FIXME: currently, it doesn't seem beneficial to omit this due to how our scheduler works sync.storage = (storage_class)(sync.storage | storage_buffer); sync.semantics = (memory_semantics)((sync.semantics | semantic_private) & ~semantic_can_reorder); @@ -422,7 +422,7 @@ void add_to_hazard_query(hazard_query *query, Instruction *instr) /* images and buffer/global memory can alias */ //TODO: more precisely, buffer images and buffer/global memory can alias if (storage & (storage_buffer | storage_image)) storage |= storage_buffer | storage_image; - if (instr->format == Format::SMEM) + if (instr->isSMEM()) query->aliasing_storage_smem |= storage; else query->aliasing_storage |= storage; @@ -457,7 +457,7 @@ HazardResult perform_hazard_query(hazard_query *query, Instruction *instr, bool } /* don't move exports so that they stay closer together */ - if (instr->format == Format::EXP) + if (instr->isEXP()) return hazard_fail_export; /* don't move non-reorderable instructions */ @@ -506,7 +506,7 @@ HazardResult perform_hazard_query(hazard_query *query, Instruction *instr, bool return hazard_fail_barrier; /* don't move memory loads/stores past potentially aliasing loads/stores */ - unsigned aliasing_storage = instr->format == Format::SMEM ? + unsigned aliasing_storage = instr->isSMEM() ? query->aliasing_storage_smem : query->aliasing_storage; if ((sync.storage & aliasing_storage) && !(sync.semantics & semantic_can_reorder)) { @@ -572,7 +572,7 @@ void schedule_SMEM(sched_ctx& ctx, Block* block, /* don't use LDS/GDS instructions to hide latency since it can * significanly worsen LDS scheduling */ - if (candidate->format == Format::DS || !can_move_down) { + if (candidate->isDS() || !can_move_down) { add_to_hazard_query(&hq, candidate.get()); ctx.mv.downwards_skip(); continue; @@ -679,7 +679,7 @@ void schedule_VMEM(sched_ctx& ctx, Block* block, assert(candidate_idx == ctx.mv.source_idx); assert(candidate_idx >= 0); aco_ptr& candidate = block->instructions[candidate_idx]; - bool is_vmem = candidate->isVMEM() || candidate->isFlatOrGlobal(); + bool is_vmem = candidate->isVMEM() || candidate->isFlatLike(); /* break when encountering another VMEM instruction, logical_start or barriers */ if (candidate->opcode == aco_opcode::p_logical_start) @@ -746,7 +746,7 @@ void schedule_VMEM(sched_ctx& ctx, Block* block, assert(candidate_idx == ctx.mv.source_idx); assert(candidate_idx < (int) block->instructions.size()); aco_ptr& candidate = block->instructions[candidate_idx]; - bool is_vmem = candidate->isVMEM() || candidate->isFlatOrGlobal(); + bool is_vmem = candidate->isVMEM() || candidate->isFlatLike(); if (candidate->opcode == aco_opcode::p_logical_end) break; @@ -820,7 +820,7 @@ void schedule_position_export(sched_ctx& ctx, Block* block, if (candidate->opcode == aco_opcode::p_logical_start) break; - if (candidate->isVMEM() || candidate->format == Format::SMEM || candidate->isFlatOrGlobal()) + if (candidate->isVMEM() || candidate->isSMEM() || candidate->isFlatLike()) break; HazardResult haz = perform_hazard_query(&hq, candidate.get(), false); @@ -856,7 +856,7 @@ void schedule_block(sched_ctx& ctx, Program *program, Block* block, live& live_v for (unsigned idx = 0; idx < block->instructions.size(); idx++) { Instruction* current = block->instructions[idx].get(); - if (block->kind & block_kind_export_end && current->format == Format::EXP) { + if (block->kind & block_kind_export_end && current->isEXP()) { unsigned target = current->exp()->dest; if (target >= V_008DFC_SQ_EXP_POS && target < V_008DFC_SQ_EXP_PRIM) { ctx.mv.current = current; @@ -867,12 +867,12 @@ void schedule_block(sched_ctx& ctx, Program *program, Block* block, live& live_v if (current->definitions.empty()) continue; - if (current->isVMEM() || current->isFlatOrGlobal()) { + if (current->isVMEM() || current->isFlatLike()) { ctx.mv.current = current; schedule_VMEM(ctx, block, live_vars.register_demand[block->index], current, idx); } - if (current->format == Format::SMEM) { + if (current->isSMEM()) { ctx.mv.current = current; schedule_SMEM(ctx, block, live_vars.register_demand[block->index], current, idx); } diff --git a/src/amd/compiler/aco_spill.cpp b/src/amd/compiler/aco_spill.cpp index be1ed489ae9..5b6339ec05f 100644 --- a/src/amd/compiler/aco_spill.cpp +++ b/src/amd/compiler/aco_spill.cpp @@ -246,10 +246,10 @@ bool should_rematerialize(aco_ptr& instr) if (instr->format != Format::VOP1 && instr->format != Format::SOP1 && instr->format != Format::PSEUDO && instr->format != Format::SOPK) return false; /* TODO: pseudo-instruction rematerialization is only supported for p_create_vector/p_parallelcopy */ - if (instr->format == Format::PSEUDO && instr->opcode != aco_opcode::p_create_vector && + if (instr->isPseudo() && instr->opcode != aco_opcode::p_create_vector && instr->opcode != aco_opcode::p_parallelcopy) return false; - if (instr->format == Format::SOPK && instr->opcode != aco_opcode::s_movk_i32) + if (instr->isSOPK() && instr->opcode != aco_opcode::s_movk_i32) return false; for (const Operand& op : instr->operands) { @@ -270,18 +270,18 @@ aco_ptr do_reload(spill_ctx& ctx, Temp tmp, Temp new_name, uint32_t std::map::iterator remat = ctx.remat.find(tmp); if (remat != ctx.remat.end()) { Instruction *instr = remat->second.instr; - assert((instr->format == Format::VOP1 || instr->format == Format::SOP1 || instr->format == Format::PSEUDO || instr->format == Format::SOPK) && "unsupported"); + assert((instr->isVOP1() || instr->isSOP1() || instr->isPseudo() || instr->isSOPK()) && "unsupported"); assert((instr->format != Format::PSEUDO || instr->opcode == aco_opcode::p_create_vector || instr->opcode == aco_opcode::p_parallelcopy) && "unsupported"); assert(instr->definitions.size() == 1 && "unsupported"); aco_ptr res; - if (instr->format == Format::VOP1) { + if (instr->isVOP1()) { res.reset(create_instruction(instr->opcode, instr->format, instr->operands.size(), instr->definitions.size())); - } else if (instr->format == Format::SOP1) { + } else if (instr->isSOP1()) { res.reset(create_instruction(instr->opcode, instr->format, instr->operands.size(), instr->definitions.size())); - } else if (instr->format == Format::PSEUDO) { + } else if (instr->isPseudo()) { res.reset(create_instruction(instr->opcode, instr->format, instr->operands.size(), instr->definitions.size())); - } else if (instr->format == Format::SOPK) { + } else if (instr->isSOPK()) { res.reset(create_instruction(instr->opcode, instr->format, instr->operands.size(), instr->definitions.size())); res->sopk()->imm = instr->sopk()->imm; } diff --git a/src/amd/compiler/aco_ssa_elimination.cpp b/src/amd/compiler/aco_ssa_elimination.cpp index 1b5d2caaa34..b3d6db75892 100644 --- a/src/amd/compiler/aco_ssa_elimination.cpp +++ b/src/amd/compiler/aco_ssa_elimination.cpp @@ -96,7 +96,7 @@ void insert_parallelcopies(ssa_elimination_ctx& ctx) Block& block = ctx.program->blocks[entry.first]; std::vector>::iterator it = block.instructions.end(); --it; - assert((*it)->format == Format::PSEUDO_BRANCH); + assert((*it)->isBranch()); aco_ptr pc{create_instruction(aco_opcode::p_parallelcopy, Format::PSEUDO, entry.second.size(), entry.second.size())}; unsigned i = 0; for (std::pair& pair : entry.second) @@ -179,7 +179,7 @@ void try_remove_invert_block(ssa_elimination_ctx& ctx, Block* block) ctx.program->blocks[succ_idx].linear_preds[i] = pred->index; Pseudo_branch_instruction *branch = pred->instructions.back()->branch(); - assert(branch->format == Format::PSEUDO_BRANCH); + assert(branch->isBranch()); branch->target[0] = succ_idx; branch->target[1] = succ_idx; } diff --git a/src/amd/compiler/aco_statistics.cpp b/src/amd/compiler/aco_statistics.cpp index b09f9a79149..7e9c825c343 100644 --- a/src/amd/compiler/aco_statistics.cpp +++ b/src/amd/compiler/aco_statistics.cpp @@ -46,7 +46,7 @@ void collect_preasm_stats(Program *program) program->statistics[statistic_instructions] += block.instructions.size(); for (aco_ptr& instr : block.instructions) { - if (instr->format == Format::SOPP && instr->sopp()->block != -1) + if (instr->isSOPP() && instr->sopp()->block != -1) program->statistics[statistic_branches]++; if (instr->opcode == aco_opcode::p_constaddr) @@ -59,7 +59,7 @@ void collect_preasm_stats(Program *program) vmem_clause_res.clear(); } - if (instr->format == Format::SMEM && !instr->operands.empty()) { + if (instr->isSMEM() && !instr->operands.empty()) { if (instr->operands[0].size() == 2) smem_clause_res.insert(Temp(0, s2)); else diff --git a/src/amd/compiler/aco_validate.cpp b/src/amd/compiler/aco_validate.cpp index c4e1cd4c358..2c53554f31a 100644 --- a/src/amd/compiler/aco_validate.cpp +++ b/src/amd/compiler/aco_validate.cpp @@ -131,7 +131,7 @@ bool validate_ir(Program* program) check(base_format == instr_info.format[(int)instr->opcode], "Wrong base format for instruction", instr.get()); /* check VOP3 modifiers */ - if (((uint32_t)instr->format & (uint32_t)Format::VOP3) && instr->format != Format::VOP3) { + if (instr->isVOP3() && instr->format != Format::VOP3) { check(base_format == Format::VOP2 || base_format == Format::VOP1 || base_format == Format::VOPC || @@ -203,12 +203,12 @@ bool validate_ir(Program* program) /* check for undefs */ for (unsigned i = 0; i < instr->operands.size(); i++) { if (instr->operands[i].isUndefined()) { - bool flat = instr->format == Format::FLAT || instr->format == Format::SCRATCH || instr->format == Format::GLOBAL; - bool can_be_undef = is_phi(instr) || instr->format == Format::EXP || - instr->format == Format::PSEUDO_REDUCTION || + bool flat = instr->isFlatLike(); + bool can_be_undef = is_phi(instr) || instr->isEXP() || + instr->isReduction() || instr->opcode == aco_opcode::p_create_vector || - (flat && i == 1) || (instr->format == Format::MIMG && (i == 1 || i == 2)) || - ((instr->format == Format::MUBUF || instr->format == Format::MTBUF) && i == 1); + (flat && i == 1) || (instr->isMIMG() && (i == 1 || i == 2)) || + ((instr->isMUBUF() || instr->isMTBUF()) && i == 1); check(can_be_undef, "Undefs can only be used in certain operands", instr.get()); } else { check(instr->operands[i].isFixed() || instr->operands[i].isTemp() || instr->operands[i].isConstant(), "Uninitialized Operand", instr.get()); @@ -218,7 +218,7 @@ bool validate_ir(Program* program) /* check subdword definitions */ for (unsigned i = 0; i < instr->definitions.size(); i++) { if (instr->definitions[i].regClass().is_subdword()) - check(instr->format == Format::PSEUDO || instr->definitions[i].bytes() <= 4, "Only Pseudo instructions can write subdword registers larger than 4 bytes", instr.get()); + check(instr->isPseudo() || instr->definitions[i].bytes() <= 4, "Only Pseudo instructions can write subdword registers larger than 4 bytes", instr.get()); } if (instr->isSALU() || instr->isVALU()) { @@ -230,19 +230,15 @@ bool validate_ir(Program* program) if (!op.isLiteral()) continue; - check(instr->format == Format::SOP1 || - instr->format == Format::SOP2 || - instr->format == Format::SOPC || - instr->format == Format::VOP1 || - instr->format == Format::VOP2 || - instr->format == Format::VOPC || + check(instr->isSOP1() || instr->isSOP2() || instr->isSOPC() || + instr->isVOP1() || instr->isVOP2() || instr->isVOPC() || (instr->isVOP3() && program->chip_class >= GFX10) || - (instr->format == Format::VOP3P && program->chip_class >= GFX10), + (instr->isVOP3P() && program->chip_class >= GFX10), "Literal applied on wrong instruction format", instr.get()); check(literal.isUndefined() || (literal.size() == op.size() && literal.constantValue() == op.constantValue()), "Only 1 Literal allowed", instr.get()); literal = op; - check(instr->isSALU() || instr->isVOP3() || instr->format == Format::VOP3P || i == 0 || i == 2, "Wrong source position for Literal argument", instr.get()); + check(instr->isSALU() || instr->isVOP3() || instr->isVOP3P() || i == 0 || i == 2, "Wrong source position for Literal argument", instr.get()); } /* check num sgprs for VALU */ @@ -254,11 +250,11 @@ bool validate_ir(Program* program) if (program->chip_class >= GFX10 && !is_shift64) const_bus_limit = 2; - uint32_t scalar_mask = instr->isVOP3() || instr->format == Format::VOP3P ? 0x7 : 0x5; + uint32_t scalar_mask = instr->isVOP3() || instr->isVOP3P() ? 0x7 : 0x5; if (instr->isSDWA()) scalar_mask = program->chip_class >= GFX9 ? 0x7 : 0x4; - if ((int) instr->format & (int) Format::VOPC || + if (instr->isVOPC() || instr->opcode == aco_opcode::v_readfirstlane_b32 || instr->opcode == aco_opcode::v_readlane_b32 || instr->opcode == aco_opcode::v_readlane_b32_e64) { @@ -313,7 +309,7 @@ bool validate_ir(Program* program) check(num_sgprs + (literal.isUndefined() ? 0 : 1) <= const_bus_limit, "Too many SGPRs/literals", instr.get()); } - if (instr->format == Format::SOP1 || instr->format == Format::SOP2) { + if (instr->isSOP1() || instr->isSOP2()) { check(instr->definitions[0].getTemp().type() == RegType::sgpr, "Wrong Definition type for SALU instruction", instr.get()); for (const Operand& op : instr->operands) { check(op.isConstant() || op.regClass().type() <= RegType::sgpr, @@ -551,7 +547,7 @@ bool validate_subdword_operand(chip_class chip, const aco_ptr& inst if (instr->opcode == aco_opcode::p_as_uniform) return byte == 0; - if (instr->format == Format::PSEUDO && chip >= GFX8) + if (instr->isPseudo() && chip >= GFX8) return true; if (instr->isSDWA() && (instr->sdwa()->sel[index] & sdwa_asuint) == (sdwa_isra | op.bytes())) return true; @@ -601,7 +597,7 @@ bool validate_subdword_definition(chip_class chip, const aco_ptr& i Definition def = instr->definitions[0]; unsigned byte = def.physReg().byte(); - if (instr->format == Format::PSEUDO && chip >= GFX8) + if (instr->isPseudo() && chip >= GFX8) return true; if (instr->isSDWA() && instr->sdwa()->dst_sel == (sdwa_isra | def.bytes())) return true; @@ -632,7 +628,7 @@ unsigned get_subdword_bytes_written(Program *program, const aco_ptr chip_class chip = program->chip_class; Definition def = instr->definitions[index]; - if (instr->format == Format::PSEUDO) + if (instr->isPseudo()) return chip >= GFX8 ? def.bytes() : def.size() * 4u; if (instr->isSDWA() && instr->sdwa()->dst_sel == (sdwa_isra | def.bytes())) return def.bytes();