From d6bfc95732da70fa7a560f41ee577a343ed9a6b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Mon, 6 Sep 2021 14:58:23 +0200 Subject: [PATCH] aco/ra: create affinities between nested phis Totals from 17143 (11.42% of 150170) affected shaders: (GFX10.3) VGPRs: 1138112 -> 1138440 (+0.03%); split: -0.00%, +0.03% CodeSize: 131235532 -> 131147080 (-0.07%); split: -0.14%, +0.07% Instrs: 24848044 -> 24775419 (-0.29%); split: -0.32%, +0.02% Latency: 599031816 -> 596005601 (-0.51%); split: -0.52%, +0.01% InvThroughput: 152059329 -> 151054105 (-0.66%); split: -0.66%, +0.00% VClause: 410951 -> 410958 (+0.00%); split: -0.01%, +0.01% Copies: 1696885 -> 1621908 (-4.42%); split: -4.64%, +0.22% Branches: 846710 -> 851052 (+0.51%); split: -0.29%, +0.80% Reviewed-by: Rhys Perry Part-of: --- src/amd/compiler/aco_register_allocation.cpp | 90 +++++++++++--------- 1 file changed, 52 insertions(+), 38 deletions(-) diff --git a/src/amd/compiler/aco_register_allocation.cpp b/src/amd/compiler/aco_register_allocation.cpp index acc250c8942..829104cf6ed 100644 --- a/src/amd/compiler/aco_register_allocation.cpp +++ b/src/amd/compiler/aco_register_allocation.cpp @@ -2293,46 +2293,29 @@ get_affinities(ra_ctx& ctx, std::vector& live_out_per_block) std::vector>::reverse_iterator rit; for (rit = block.instructions.rbegin(); rit != block.instructions.rend(); ++rit) { aco_ptr& instr = *rit; - if (is_phi(instr)) { - if (instr->definitions[0].isKill() || instr->definitions[0].isFixed()) { - live.erase(instr->definitions[0].tempId()); - continue; - } - /* collect information about affinity-related temporaries */ - std::vector affinity_related; - /* affinity_related[0] is the last seen affinity-related temp */ - affinity_related.emplace_back(instr->definitions[0].getTemp()); - affinity_related.emplace_back(instr->definitions[0].getTemp()); - for (const Operand& op : instr->operands) { - if (op.isTemp() && op.isKill() && - op.regClass() == instr->definitions[0].regClass()) { - affinity_related.emplace_back(op.getTemp()); - temp_to_phi_ressources[op.tempId()] = phi_ressources.size(); - } - } - phi_ressources.emplace_back(std::move(affinity_related)); - } else { - /* add vector affinities */ - if (instr->opcode == aco_opcode::p_create_vector) { - for (const Operand& op : instr->operands) { - if (op.isTemp() && op.isFirstKill() && - op.getTemp().type() == instr->definitions[0].getTemp().type()) - ctx.vectors[op.tempId()] = instr.get(); - } - } else if (instr->format == Format::MIMG && instr->operands.size() > 4) { - for (unsigned i = 3; i < instr->operands.size(); i++) - ctx.vectors[instr->operands[i].tempId()] = instr.get(); - } + if (is_phi(instr)) + break; - if (instr->opcode == aco_opcode::p_split_vector && - instr->operands[0].isFirstKillBeforeDef()) - ctx.split_vectors[instr->operands[0].tempId()] = instr.get(); - - /* add operands to live variables */ + /* add vector affinities */ + if (instr->opcode == aco_opcode::p_create_vector) { for (const Operand& op : instr->operands) { - if (op.isTemp()) - live.insert(op.tempId()); + if (op.isTemp() && op.isFirstKill() && + op.getTemp().type() == instr->definitions[0].getTemp().type()) + ctx.vectors[op.tempId()] = instr.get(); } + } else if (instr->format == Format::MIMG && instr->operands.size() > 4) { + for (unsigned i = 3; i < instr->operands.size(); i++) + ctx.vectors[instr->operands[i].tempId()] = instr.get(); + } + + if (instr->opcode == aco_opcode::p_split_vector && + instr->operands[0].isFirstKillBeforeDef()) + ctx.split_vectors[instr->operands[0].tempId()] = instr.get(); + + /* add operands to live variables */ + for (const Operand& op : instr->operands) { + if (op.isTemp()) + live.insert(op.tempId()); } /* erase definitions from live */ @@ -2379,10 +2362,41 @@ get_affinities(ra_ctx& ctx, std::vector& live_out_per_block) } } } + + /* collect phi affinities */ + for (; rit != block.instructions.rend(); ++rit) { + aco_ptr& instr = *rit; + assert(is_phi(instr)); + + live.erase(instr->definitions[0].tempId()); + if (instr->definitions[0].isKill() || instr->definitions[0].isFixed()) + continue; + + assert(instr->definitions[0].isTemp()); + std::unordered_map::iterator it = + temp_to_phi_ressources.find(instr->definitions[0].tempId()); + unsigned index = phi_ressources.size(); + std::vector* affinity_related; + if (it != temp_to_phi_ressources.end()) { + index = it->second; + phi_ressources[index][0] = instr->definitions[0].getTemp(); + affinity_related = &phi_ressources[index]; + } else { + phi_ressources.emplace_back(std::vector{instr->definitions[0].getTemp()}); + affinity_related = &phi_ressources.back(); + } + + for (unsigned i = 0; i < instr->operands.size(); i++) { + const Operand& op = instr->operands[i]; + if (op.isTemp() && op.isKill() && op.regClass() == instr->definitions[0].regClass()) { + affinity_related->emplace_back(op.getTemp()); + temp_to_phi_ressources[op.tempId()] = index; + } + } + } } /* create affinities */ for (std::vector& vec : phi_ressources) { - assert(vec.size() > 1); for (unsigned i = 1; i < vec.size(); i++) if (vec[i].id() != vec[0].id()) ctx.assignments[vec[i].id()].affinity = vec[0].id();