From 4cb73cb5f3ae0e2ca89f321b249bbde96d945e8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Mon, 25 Mar 2024 15:27:56 +0100 Subject: [PATCH] aco: defer instruction size from aco::Format in create_instruction() rather than using the template argument. Part-of: --- src/amd/compiler/aco_ir.cpp | 38 +++++++++++++++++++++++++++++++++++++ src/amd/compiler/aco_ir.h | 13 ++++++++----- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/amd/compiler/aco_ir.cpp b/src/amd/compiler/aco_ir.cpp index ac0a623f1fa..e20a8e7960d 100644 --- a/src/amd/compiler/aco_ir.cpp +++ b/src/amd/compiler/aco_ir.cpp @@ -1392,4 +1392,42 @@ Instruction::isTrans() const noexcept instr_info.classes[(int)opcode] == instr_class::valu_double_transcendental; } +size_t +get_instr_data_size(Format format) +{ + switch (format) { + case Format::SOP1: + case Format::SOP2: + case Format::SOPC: + case Format::SOPK: + case Format::SOPP: return sizeof(SALU_instruction); + case Format::SMEM: return sizeof(SMEM_instruction); + case Format::PSEUDO: return sizeof(Pseudo_instruction); + case Format::PSEUDO_BARRIER: return sizeof(Pseudo_barrier_instruction); + case Format::PSEUDO_REDUCTION: return sizeof(Pseudo_reduction_instruction); + case Format::PSEUDO_BRANCH: return sizeof(Pseudo_branch_instruction); + case Format::DS: return sizeof(DS_instruction); + case Format::FLAT: + case Format::GLOBAL: + case Format::SCRATCH: return sizeof(FLAT_instruction); + case Format::LDSDIR: return sizeof(LDSDIR_instruction); + case Format::MTBUF: return sizeof(MTBUF_instruction); + case Format::MUBUF: return sizeof(MUBUF_instruction); + case Format::MIMG: return sizeof(MIMG_instruction); + case Format::VOPD: return sizeof(VOPD_instruction); + case Format::VINTERP_INREG: return sizeof(VINTERP_inreg_instruction); + case Format::VINTRP: return sizeof(VINTRP_instruction); + case Format::EXP: return sizeof(Export_instruction); + default: + if ((uint16_t)format & (uint16_t)Format::DPP16) + return sizeof(DPP16_instruction); + else if ((uint16_t)format & (uint16_t)Format::DPP8) + return sizeof(DPP8_instruction); + else if ((uint16_t)format & (uint16_t)Format::SDWA) + return sizeof(SDWA_instruction); + else + return sizeof(VALU_instruction); + } +} + } // namespace aco diff --git a/src/amd/compiler/aco_ir.h b/src/amd/compiler/aco_ir.h index 0b1791139c7..8648582df1e 100644 --- a/src/amd/compiler/aco_ir.h +++ b/src/amd/compiler/aco_ir.h @@ -1670,21 +1670,24 @@ struct instr_deleter_functor { template using aco_ptr = std::unique_ptr; +size_t get_instr_data_size(Format format); + template Instruction* create_instruction(aco_opcode opcode, Format format, uint32_t num_operands, uint32_t num_definitions) { - std::size_t size = - sizeof(T) + num_operands * sizeof(Operand) + num_definitions * sizeof(Definition); - void* data = instruction_buffer->allocate(size, alignof(uint32_t)); - memset(data, 0, size); + size_t size = get_instr_data_size(format); + size_t total_size = size + num_operands * sizeof(Operand) + num_definitions * sizeof(Definition); + + void* data = instruction_buffer->allocate(total_size, alignof(uint32_t)); + memset(data, 0, total_size); Instruction* inst = (Instruction*)data; inst->opcode = opcode; inst->format = format; - uint16_t operands_offset = sizeof(T) - offsetof(Instruction, operands); + uint16_t operands_offset = size - offsetof(Instruction, operands); inst->operands = aco::span(operands_offset, num_operands); uint16_t definitions_offset = (char*)inst->operands.end() - (char*)&inst->definitions; inst->definitions = aco::span(definitions_offset, num_definitions);