From 8023dcd71ee9eb1c5db012d716e959e973323906 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Daniel=20Sch=C3=BCrmann?= Date: Tue, 29 Oct 2019 11:58:21 +0100 Subject: [PATCH] aco: fix live-range splits of phis Reviewed-by: Rhys Perry --- src/amd/compiler/aco_register_allocation.cpp | 37 ++++++++++++-------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/amd/compiler/aco_register_allocation.cpp b/src/amd/compiler/aco_register_allocation.cpp index 621bc1f7636..9e3d796dc2f 100644 --- a/src/amd/compiler/aco_register_allocation.cpp +++ b/src/amd/compiler/aco_register_allocation.cpp @@ -1272,6 +1272,29 @@ void register_allocation(Program *program, std::vector> live_out_ /* process parallelcopy */ for (std::pair pc : parallelcopy) { + /* see if it's a copy from a different phi */ + //TODO: prefer moving some previous phis over live-ins + //TODO: somehow prevent phis fixed before the RA from being updated (shouldn't be a problem in practice since they can only be fixed to exec) + Instruction *prev_phi = NULL; + std::vector>::iterator phi_it; + for (phi_it = instructions.begin(); phi_it != instructions.end(); ++phi_it) { + if ((*phi_it)->definitions[0].tempId() == pc.first.tempId()) + prev_phi = phi_it->get(); + } + phi_it = it; + while (!prev_phi && is_phi(*++phi_it)) { + if ((*phi_it)->definitions[0].tempId() == pc.first.tempId()) + prev_phi = phi_it->get(); + } + if (prev_phi) { + /* if so, just update that phi's register */ + prev_phi->definitions[0].setFixed(pc.second.physReg()); + ctx.assignments[prev_phi->definitions[0].tempId()] = {pc.second.physReg(), pc.second.regClass()}; + for (unsigned reg = pc.second.physReg(); reg < pc.second.physReg() + pc.second.size(); reg++) + register_file[reg] = prev_phi->definitions[0].tempId(); + continue; + } + /* rename */ std::map::iterator orig_it = ctx.orig_names.find(pc.first.tempId()); Temp orig = pc.first.getTemp(); @@ -1282,20 +1305,6 @@ void register_allocation(Program *program, std::vector> live_out_ renames[block.index][orig.id()] = pc.second.getTemp(); renames[block.index][pc.second.tempId()] = pc.second.getTemp(); - /* see if it's a copy from a previous phi */ - //TODO: prefer moving some previous phis over live-ins - //TODO: somehow prevent phis fixed before the RA from being updated (shouldn't be a problem in practice since they can only be fixed to exec) - Instruction *prev_phi = NULL; - for (auto it2 = instructions.begin(); it2 != instructions.end(); ++it2) { - if ((*it2)->definitions[0].tempId() == pc.first.tempId()) - prev_phi = it2->get(); - } - if (prev_phi) { - /* if so, just update that phi */ - prev_phi->definitions[0] = pc.second; - continue; - } - /* otherwise, this is a live-in and we need to create a new phi * to move it in this block's predecessors */ aco_opcode opcode = pc.first.getTemp().is_linear() ? aco_opcode::p_linear_phi : aco_opcode::p_phi; -- 2.30.2