From eb557fd090db348bc170efb634efae7ebdd5be13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Thu, 14 Aug 2025 18:46:00 +0200 Subject: [PATCH] aco/ra: add vector_info::index to indicate the Operand's index into the vector This simplifies the code and will allow for a mismatch between the index and the Operand's temporary. Totals from 28 (0.04% of 79839) affected shaders: (Navi48) Instrs: 18453 -> 18440 (-0.07%); split: -0.08%, +0.01% CodeSize: 98588 -> 98532 (-0.06%); split: -0.06%, +0.00% Copies: 1347 -> 1333 (-1.04%); split: -1.11%, +0.07% VALU: 10431 -> 10417 (-0.13%); split: -0.14%, +0.01% Part-of: --- src/amd/compiler/aco_register_allocation.cpp | 44 +++++++++----------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/src/amd/compiler/aco_register_allocation.cpp b/src/amd/compiler/aco_register_allocation.cpp index 7f8c804e84f..cb1db265953 100644 --- a/src/amd/compiler/aco_register_allocation.cpp +++ b/src/amd/compiler/aco_register_allocation.cpp @@ -109,9 +109,10 @@ struct PhysRegIterator { }; struct vector_info { - vector_info() : is_weak(false), num_parts(0), parts(NULL) {} - vector_info(Instruction* instr, unsigned start = 0, bool weak = false) - : is_weak(weak), num_parts(instr->operands.size() - start - (instr_disables_wqm(instr) * 2)), + vector_info() : is_weak(false), index(0), num_parts(0), parts(NULL) {} + vector_info(Instruction* instr, unsigned idx, unsigned start = 0, bool weak = false) + : is_weak(weak), index(idx), + num_parts(instr->operands.size() - start - (instr_disables_wqm(instr) * 2)), parts(instr->operands.begin() + start) { if (parts[0].isVectorAligned()) { @@ -124,6 +125,7 @@ struct vector_info { /* If true, then we should stop trying to form a vector if anything goes wrong. Useful for when * the cost of failing does not introduce copies. */ bool is_weak; + uint16_t index; uint32_t num_parts; Operand* parts; }; @@ -1750,13 +1752,8 @@ get_reg_vector(ra_ctx& ctx, const RegisterFile& reg_file, Temp temp, aco_ptr& instr, } } - unsigned index = 0; - for (; index < dest_vector.num_parts; index++) { - if (dest_vector.parts[index].isTemp() && - dest_vector.parts[index].tempId() == instr->definitions[0].tempId()) - break; - } - assert(index != dest_vector.num_parts); - for (int i = instr->operands.size() - 1; i >= 0; i--) { const Operand& op = instr->operands[i]; if (!op.isTemp() || op.regClass() != instr->definitions[0].regClass()) continue; - src_vectors[i].parts[index] = op; + src_vectors[i].parts[dest_vector.index] = op; + src_vectors[i].index = dest_vector.index; ctx.vectors[op.tempId()] = src_vectors[i]; } } @@ -3056,10 +3046,11 @@ get_affinities(ra_ctx& ctx) /* add vector affinities */ if (instr->opcode == aco_opcode::p_create_vector) { - for (const Operand& op : instr->operands) { + for (unsigned i = 0; i < instr->operands.size(); i++) { + Operand op = instr->operands[i]; if (op.isTemp() && op.isFirstKill() && op.getTemp().type() == instr->definitions[0].getTemp().type()) - ctx.vectors[op.tempId()] = vector_info(instr.get()); + ctx.vectors[op.tempId()] = vector_info(instr.get(), i); } } else if (instr->format == Format::MIMG && instr->operands.size() > 4 && !instr->mimg().strict_wqm) { @@ -3068,9 +3059,11 @@ get_affinities(ra_ctx& ctx) unsigned op_count = instr->operands.size() - (instr->mimg().disable_wqm * 2); for (unsigned i = 3, vector_begin = 3; i < op_count; i++) { if (is_vector || instr->operands[i].isVectorAligned()) - ctx.vectors[instr->operands[i].tempId()] = vector_info(instr.get(), vector_begin); + ctx.vectors[instr->operands[i].tempId()] = + vector_info(instr.get(), i - vector_begin, vector_begin); else if (ctx.program->gfx_level < GFX12 && !instr->operands[3].isVectorAligned()) - ctx.vectors[instr->operands[i].tempId()] = vector_info(instr.get(), 3, true); + ctx.vectors[instr->operands[i].tempId()] = + vector_info(instr.get(), i - 3, 3, true); is_vector = instr->operands[i].isVectorAligned(); vector_begin = is_vector ? vector_begin : i + 1; } @@ -3098,7 +3091,8 @@ get_affinities(ra_ctx& ctx) bool is_vector = false; for (unsigned i = 0, vector_begin = 0; i < instr->operands.size(); i++) { if (is_vector || instr->operands[i].isVectorAligned()) - ctx.vectors[instr->operands[i].tempId()] = vector_info(instr.get(), vector_begin); + ctx.vectors[instr->operands[i].tempId()] = + vector_info(instr.get(), i - vector_begin, vector_begin); is_vector = instr->operands[i].isVectorAligned(); vector_begin = is_vector ? vector_begin : i + 1; }