From bb1c06343d85158bf4ac12b90e0f768cd7267640 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Tue, 26 Jan 2021 19:05:23 +0100 Subject: [PATCH] aco/ra: refactor register assignment for vector operands No functional changes. Reviewed-by: Tony Wasserka Part-of: --- src/amd/compiler/aco_register_allocation.cpp | 98 ++++++++++++-------- 1 file changed, 58 insertions(+), 40 deletions(-) diff --git a/src/amd/compiler/aco_register_allocation.cpp b/src/amd/compiler/aco_register_allocation.cpp index 4d519cd884b..441fcf8cc79 100644 --- a/src/amd/compiler/aco_register_allocation.cpp +++ b/src/amd/compiler/aco_register_allocation.cpp @@ -1388,6 +1388,59 @@ bool is_mimg_vaddr_intact(ra_ctx& ctx, RegisterFile& reg_file, Instruction *inst return true; } +std::pair get_reg_vector(ra_ctx& ctx, + RegisterFile& reg_file, + Temp temp, + aco_ptr& instr) +{ + Instruction* vec = ctx.vectors[temp.id()]; + unsigned first_operand = vec->format == Format::MIMG ? 3 : 0; + unsigned our_offset = 0; + for (unsigned i = first_operand; i < vec->operands.size(); i++) { + Operand& op = vec->operands[i]; + if (op.isTemp() && op.tempId() == temp.id()) + break; + else + our_offset += op.bytes(); + } + + if (vec->format != Format::MIMG || is_mimg_vaddr_intact(ctx, reg_file, vec)) { + unsigned their_offset = 0; + /* check for every operand of the vector + * - whether the operand is assigned and + * - we can use the register relative to that operand + */ + for (unsigned i = first_operand; i < vec->operands.size(); i++) { + Operand& op = vec->operands[i]; + if (op.isTemp() && + op.tempId() != temp.id() && + op.getTemp().type() == temp.type() && + ctx.assignments[op.tempId()].assigned) { + PhysReg reg = ctx.assignments[op.tempId()].reg; + reg.reg_b += (our_offset - their_offset); + if (get_reg_specified(ctx, reg_file, temp.regClass(), instr, reg)) + return {reg, true}; + } + their_offset += op.bytes(); + } + + /* We didn't find a register relative to other vector operands. + * Try to find new space which fits the whole vector. + */ + RegClass vec_rc = RegClass::get(temp.type(), their_offset); + DefInfo info(ctx, ctx.pseudo_dummy, vec_rc, -1); + std::pair res = get_reg_simple(ctx, reg_file, info); + PhysReg reg = res.first; + if (res.second) { + reg.reg_b += our_offset; + /* make sure to only use byte offset if the instruction supports it */ + if (get_reg_specified(ctx, reg_file, temp.regClass(), instr, reg)) + return {reg, true}; + } + } + return {{}, false}; +} + PhysReg get_reg(ra_ctx& ctx, RegisterFile& reg_file, Temp temp, @@ -1417,51 +1470,16 @@ PhysReg get_reg(ra_ctx& ctx, return reg; } + std::pair res; + if (ctx.vectors.find(temp.id()) != ctx.vectors.end()) { - Instruction* vec = ctx.vectors[temp.id()]; - unsigned first_operand = vec->format == Format::MIMG ? 3 : 0; - unsigned byte_offset = 0; - for (unsigned i = first_operand; i < vec->operands.size(); i++) { - Operand& op = vec->operands[i]; - if (op.isTemp() && op.tempId() == temp.id()) - break; - else - byte_offset += op.bytes(); - } - - if (vec->format != Format::MIMG || is_mimg_vaddr_intact(ctx, reg_file, vec)) { - unsigned k = 0; - for (unsigned i = first_operand; i < vec->operands.size(); i++) { - Operand& op = vec->operands[i]; - if (op.isTemp() && - op.tempId() != temp.id() && - op.getTemp().type() == temp.type() && - ctx.assignments[op.tempId()].assigned) { - PhysReg reg = ctx.assignments[op.tempId()].reg; - reg.reg_b += (byte_offset - k); - if (get_reg_specified(ctx, reg_file, temp.regClass(), instr, reg)) - return reg; - } - k += op.bytes(); - } - - RegClass vec_rc = RegClass::get(temp.type(), k); - DefInfo info(ctx, ctx.pseudo_dummy, vec_rc, -1); - std::pair res = get_reg_simple(ctx, reg_file, info); - PhysReg reg = res.first; - if (res.second) { - reg.reg_b += byte_offset; - /* make sure to only use byte offset if the instruction supports it */ - if (get_reg_specified(ctx, reg_file, temp.regClass(), instr, reg)) - return reg; - } - } + res = get_reg_vector(ctx, reg_file, temp, instr); + if (res.second) + return res.first; } DefInfo info(ctx, instr, temp.regClass(), operand_index); - std::pair res; - if (!ctx.policy.skip_optimistic_path) { /* try to find space without live-range splits */ res = get_reg_simple(ctx, reg_file, info);