From be93e38152248145a00a8a659b1e9cb58676c104 Mon Sep 17 00:00:00 2001 From: Georg Lehmann Date: Tue, 2 Apr 2024 16:36:20 +0200 Subject: [PATCH] aco/vn: remove instruction hash templates This reuses the instruction data size helper used for creating instruction. It also removes the hashing of the aco::spans used for operands and definitions, which was redundant with hash finalization. Reviewed-by: Rhys Perry Part-of: --- src/amd/compiler/aco_ir.cpp | 2 +- src/amd/compiler/aco_ir.h | 2 + src/amd/compiler/aco_opt_value_numbering.cpp | 74 ++++++-------------- 3 files changed, 23 insertions(+), 55 deletions(-) diff --git a/src/amd/compiler/aco_ir.cpp b/src/amd/compiler/aco_ir.cpp index 55f85594cae..9b6795f1940 100644 --- a/src/amd/compiler/aco_ir.cpp +++ b/src/amd/compiler/aco_ir.cpp @@ -1392,7 +1392,7 @@ Instruction::isTrans() const noexcept instr_info.classes[(int)opcode] == instr_class::valu_double_transcendental; } -static size_t +size_t get_instr_data_size(Format format) { switch (format) { diff --git a/src/amd/compiler/aco_ir.h b/src/amd/compiler/aco_ir.h index 7a58efa4292..d554af5bb54 100644 --- a/src/amd/compiler/aco_ir.h +++ b/src/amd/compiler/aco_ir.h @@ -1668,6 +1668,8 @@ struct instr_deleter_functor { template using aco_ptr = std::unique_ptr; +size_t get_instr_data_size(Format format); + Instruction* create_instruction(aco_opcode opcode, Format format, uint32_t num_operands, uint32_t num_definitions); diff --git a/src/amd/compiler/aco_opt_value_numbering.cpp b/src/amd/compiler/aco_opt_value_numbering.cpp index 7183bfcca44..72f1d191667 100644 --- a/src/amd/compiler/aco_opt_value_numbering.cpp +++ b/src/amd/compiler/aco_opt_value_numbering.cpp @@ -47,34 +47,6 @@ murmur_32_scramble(uint32_t h, uint32_t k) return h; } -template -uint32_t -hash_murmur_32(Instruction* instr) -{ - uint32_t hash = uint32_t(instr->format) << 16 | uint32_t(instr->opcode); - - for (const Operand& op : instr->operands) - hash = murmur_32_scramble(hash, op.constantValue()); - - /* skip format, opcode and pass_flags */ - for (unsigned i = 2; i < (sizeof(T) >> 2); i++) { - uint32_t u; - /* Accesses it though a byte array, so doesn't violate the strict aliasing rule */ - memcpy(&u, reinterpret_cast(instr) + i * 4, 4); - hash = murmur_32_scramble(hash, u); - } - - /* Finalize. */ - uint32_t len = instr->operands.size() + instr->definitions.size() + sizeof(T); - hash ^= len; - hash ^= hash >> 16; - hash *= 0x85ebca6b; - hash ^= hash >> 13; - hash *= 0xc2b2ae35; - hash ^= hash >> 16; - return hash; -} - struct InstrHash { /* This hash function uses the Murmur3 algorithm written by Austin Appleby * https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp @@ -84,36 +56,30 @@ struct InstrHash { */ std::size_t operator()(Instruction* instr) const { - if (instr->isDPP16()) - return hash_murmur_32(instr); + uint32_t hash = uint32_t(instr->format) << 16 | uint32_t(instr->opcode); - if (instr->isDPP8()) - return hash_murmur_32(instr); + for (const Operand& op : instr->operands) + hash = murmur_32_scramble(hash, op.constantValue()); - if (instr->isSDWA()) - return hash_murmur_32(instr); + size_t data_size = get_instr_data_size(instr->format); - if (instr->isVINTERP_INREG()) - return hash_murmur_32(instr); - - if (instr->isVALU()) - return hash_murmur_32(instr); - - switch (instr->format) { - 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::EXP: return hash_murmur_32(instr); - case Format::MUBUF: return hash_murmur_32(instr); - case Format::MIMG: return hash_murmur_32(instr); - case Format::MTBUF: return hash_murmur_32(instr); - case Format::FLAT: return hash_murmur_32(instr); - case Format::PSEUDO_BRANCH: return hash_murmur_32(instr); - case Format::PSEUDO_REDUCTION: return hash_murmur_32(instr); - default: return hash_murmur_32(instr); + /* skip format, opcode and pass_flags and op/def spans */ + for (unsigned i = sizeof(Instruction) >> 2; i < (data_size >> 2); i++) { + uint32_t u; + /* Accesses it though a byte array, so doesn't violate the strict aliasing rule */ + memcpy(&u, reinterpret_cast(instr) + i * 4, 4); + hash = murmur_32_scramble(hash, u); } + + /* Finalize. */ + uint32_t len = instr->operands.size() + instr->definitions.size(); + hash ^= len; + hash ^= hash >> 16; + hash *= 0x85ebca6b; + hash ^= hash >> 13; + hash *= 0xc2b2ae35; + hash ^= hash >> 16; + return hash; } };