From 99d032f3cd1a7ea359f03968a30a89a18830868c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Daniel=20Sch=C3=BCrmann?= Date: Tue, 21 Jan 2020 12:11:12 +0100 Subject: [PATCH] aco: fix register allocation with multiple live-range splits This patch fixes register allocation if multiple live-range splits occur to the same variable within one instruction. Reviewed-by: Rhys Perry Part-of: --- src/amd/compiler/aco_register_allocation.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/amd/compiler/aco_register_allocation.cpp b/src/amd/compiler/aco_register_allocation.cpp index 55c41dcdb06..ab61d5515f2 100644 --- a/src/amd/compiler/aco_register_allocation.cpp +++ b/src/amd/compiler/aco_register_allocation.cpp @@ -145,6 +145,15 @@ void update_renames(ra_ctx& ctx, std::array& reg_file, if (copy.second.isTemp()) continue; + /* check if we we moved another parallelcopy definition */ + for (std::pair& other : parallelcopies) { + if (!other.second.isTemp()) + continue; + if (copy.first.getTemp() == other.second.getTemp()) { + copy.first.setTemp(other.first.getTemp()); + copy.first.setFixed(other.first.physReg()); + } + } // FIXME: if a definition got moved, change the target location and remove the parallelcopy copy.second.setTemp(Temp(ctx.program->allocateId(), copy.second.regClass())); ctx.assignments[copy.second.tempId()] = {copy.second.physReg(), copy.second.regClass()}; @@ -1744,14 +1753,11 @@ void register_allocation(Program *program, std::vector> live_out_ /* it might happen that the operand is already renamed. we have to restore the original name. */ std::map::iterator it = ctx.orig_names.find(pc->operands[i].tempId()); - if (it != ctx.orig_names.end()) - pc->operands[i].setTemp(it->second); - unsigned orig_id = pc->operands[i].tempId(); - ctx.orig_names[pc->definitions[i].tempId()] = pc->operands[i].getTemp(); - - pc->operands[i].setTemp(read_variable(pc->operands[i].getTemp(), block.index)); - renames[block.index][orig_id] = pc->definitions[i].getTemp(); + Temp orig = it != ctx.orig_names.end() ? it->second : pc->operands[i].getTemp(); + ctx.orig_names[pc->definitions[i].tempId()] = orig; + renames[block.index][orig.id()] = pc->definitions[i].getTemp(); renames[block.index][pc->definitions[i].tempId()] = pc->definitions[i].getTemp(); + std::map::iterator phi = phi_map.find(pc->operands[i].tempId()); if (phi != phi_map.end()) phi->second.uses.emplace(pc.get()); -- 2.30.2