From 69b6069dd288455cdb2655284c592a85d17df273 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Daniel=20Sch=C3=BCrmann?= Date: Wed, 11 Mar 2020 08:38:48 +0100 Subject: [PATCH] aco: refactor try_remove_trivial_phi() in RA Minor refactoring to avoid some pointer chasing. This patch also changes the live_out argument to be passed by reference to avoid an unnecessary copy. Reviewed-by: Rhys Perry Part-of: --- src/amd/compiler/aco_ir.h | 2 +- src/amd/compiler/aco_register_allocation.cpp | 46 ++++++++++---------- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/amd/compiler/aco_ir.h b/src/amd/compiler/aco_ir.h index 8b05482ff92..2a52d6b44de 100644 --- a/src/amd/compiler/aco_ir.h +++ b/src/amd/compiler/aco_ir.h @@ -1471,7 +1471,7 @@ void value_numbering(Program* program); void optimize(Program* program); void setup_reduce_temp(Program* program); void lower_to_cssa(Program* program, live& live_vars, const struct radv_nir_compiler_options *options); -void register_allocation(Program *program, std::vector> live_out_per_block); +void register_allocation(Program *program, std::vector>& live_out_per_block); void ssa_elimination(Program* program); void lower_to_hw_instr(Program* program); void schedule_program(Program* program, live& live_vars); diff --git a/src/amd/compiler/aco_register_allocation.cpp b/src/amd/compiler/aco_register_allocation.cpp index 92006d20561..aab1cd3745f 100644 --- a/src/amd/compiler/aco_register_allocation.cpp +++ b/src/amd/compiler/aco_register_allocation.cpp @@ -1097,7 +1097,7 @@ bool operand_can_use_reg(aco_ptr& instr, unsigned idx, PhysReg reg) } /* end namespace */ -void register_allocation(Program *program, std::vector> live_out_per_block) +void register_allocation(Program *program, std::vector>& live_out_per_block) { ra_ctx ctx(program); @@ -1118,7 +1118,7 @@ void register_allocation(Program *program, std::vector> live_out_ std::map affinities; std::function read_variable; std::function handle_live_in; - std::function::iterator)> try_remove_trivial_phi; + std::function try_remove_trivial_phi; read_variable = [&](Temp val, unsigned block_idx) -> Temp { std::unordered_map::iterator it = renames[block_idx].find(val.id()); @@ -1198,27 +1198,33 @@ void register_allocation(Program *program, std::vector> live_out_ return new_val; }; - try_remove_trivial_phi = [&] (std::map::iterator info) -> Temp { + try_remove_trivial_phi = [&] (Temp temp) -> void { + std::map::iterator info = phi_map.find(temp.id()); + + if (info == phi_map.end() || !sealed[info->second.block_idx]) + return; + assert(info->second.block_idx != 0); Instruction* phi = info->second.phi; Temp same = Temp(); - Definition def = phi->definitions[0]; + /* a phi node is trivial if all operands are the same as the definition of the phi */ for (const Operand& op : phi->operands) { const Temp t = op.getTemp(); - if (t == same || t == def.getTemp()) + if (t == same || t == def.getTemp()) { + assert(t == same || op.physReg() == def.physReg()); continue; - if (!(same == Temp()) || !(op.physReg() == def.physReg())) { - /* phi is not trivial */ - return def.getTemp(); } + if (same != Temp()) + return; + same = t; } - assert(!(same == Temp() || same == def.getTemp())); + assert(same != Temp() || same == def.getTemp()); /* reroute all uses to same and remove phi */ - std::vector::iterator> phi_users; + std::vector phi_users; std::map::iterator same_phi_info = phi_map.find(same.id()); for (Instruction* instr : info->second.uses) { assert(phi != instr); @@ -1228,9 +1234,8 @@ void register_allocation(Program *program, std::vector> live_out_ if (instr->definitions.empty()) continue; - std::map::iterator it = phi_map.find(instr->definitions[0].tempId()); - if (it != phi_map.end() && it != info) - phi_users.emplace_back(it); + if (instr->definitions[0].getTemp() != temp) + phi_users.emplace_back(instr->definitions[0].getTemp()); } for (Operand& op : instr->operands) { if (op.isTemp() && op.tempId() == def.tempId()) { @@ -1249,16 +1254,12 @@ void register_allocation(Program *program, std::vector> live_out_ renames[i][orig_var] = same; } - unsigned block_idx = info->second.block_idx; phi->definitions.clear(); /* this indicates that the phi can be removed */ phi_map.erase(info); - for (auto it : phi_users) { - if (sealed[it->second.block_idx]) - try_remove_trivial_phi(it); - } + for (Temp t : phi_users) + try_remove_trivial_phi(t); - /* due to the removal of other phis, the name might have changed once again! */ - return renames[block_idx][orig_var]; + return; }; std::map vectors; @@ -2019,6 +2020,8 @@ void register_allocation(Program *program, std::vector> live_out_ } } if (all_filled) { + sealed[succ_idx] = true; + /* finish incomplete phis and check if they became trivial */ for (Instruction* phi : incomplete_phis[succ_idx]) { std::vector preds = phi->definitions[0].getTemp().is_linear() ? succ.linear_preds : succ.logical_preds; @@ -2026,7 +2029,7 @@ void register_allocation(Program *program, std::vector> live_out_ phi->operands[i].setTemp(read_variable(phi->operands[i].getTemp(), preds[i])); phi->operands[i].setFixed(ctx.assignments[phi->operands[i].tempId()].reg); } - try_remove_trivial_phi(phi_map.find(phi->definitions[0].tempId())); + try_remove_trivial_phi(phi->definitions[0].getTemp()); } /* complete the original phi nodes, but no need to check triviality */ for (aco_ptr& instr : succ.instructions) { @@ -2045,7 +2048,6 @@ void register_allocation(Program *program, std::vector> live_out_ phi->second.uses.emplace(instr.get()); } } - sealed[succ_idx] = true; } } } /* end for BB */ -- 2.30.2