aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Schürmann <[email protected]>2020-01-13 15:13:19 +0100
committerDaniel Schürmann <[email protected]>2020-01-16 16:01:59 +0100
commit427e5eeb02053745f4f1c7a655058ce3d804c206 (patch)
tree93b97c2438387e3d4d7b3bb06a0cae936de2ea1e
parentd098024c40ee6bd12804833b71a554380df2d51d (diff)
aco: handle phi affinities transitively through parallelcopies
This can coalesce most unnecessarily inserted parallelcopies from lowering to CSSA. v2: refactor loop a bit to make it more efficient and readable. Reviewed-by: Rhys Perry <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3385>
-rw-r--r--src/amd/compiler/aco_register_allocation.cpp56
1 files changed, 37 insertions, 19 deletions
diff --git a/src/amd/compiler/aco_register_allocation.cpp b/src/amd/compiler/aco_register_allocation.cpp
index a137a952d43..ec8838d97ed 100644
--- a/src/amd/compiler/aco_register_allocation.cpp
+++ b/src/amd/compiler/aco_register_allocation.cpp
@@ -1112,18 +1112,10 @@ void register_allocation(Program *program, std::vector<std::set<Temp>> live_out_
std::vector<aco_ptr<Instruction>>::reverse_iterator rit;
for (rit = block.instructions.rbegin(); rit != block.instructions.rend(); ++rit) {
aco_ptr<Instruction>& instr = *rit;
- if (!is_phi(instr)) {
- for (const Operand& op : instr->operands) {
- if (op.isTemp())
- live.emplace(op.getTemp());
- }
- if (instr->opcode == aco_opcode::p_create_vector) {
- for (const Operand& op : instr->operands) {
- if (op.isTemp() && op.getTemp().type() == instr->definitions[0].getTemp().type())
- vectors[op.tempId()] = instr.get();
- }
- }
- } else if (!instr->definitions[0].isKill() && !instr->definitions[0].isFixed()) {
+ if (is_phi(instr)) {
+ live.erase(instr->definitions[0].getTemp());
+ if (instr->definitions[0].isKill() || instr->definitions[0].isFixed())
+ continue;
/* collect information about affinity-related temporaries */
std::vector<Temp> affinity_related;
/* affinity_related[0] is the last seen affinity-related temp */
@@ -1136,15 +1128,41 @@ void register_allocation(Program *program, std::vector<std::set<Temp>> live_out_
}
}
phi_ressources.emplace_back(std::move(affinity_related));
+ continue;
}
- /* erase from live */
- for (const Definition& def : instr->definitions) {
- if (def.isTemp()) {
- live.erase(def.getTemp());
- std::map<unsigned, unsigned>::iterator it = temp_to_phi_ressources.find(def.tempId());
- if (it != temp_to_phi_ressources.end() && def.regClass() == phi_ressources[it->second][0].regClass())
- phi_ressources[it->second][0] = def.getTemp();
+ /* add vector affinities */
+ if (instr->opcode == aco_opcode::p_create_vector) {
+ for (const Operand& op : instr->operands) {
+ if (op.isTemp() && op.getTemp().type() == instr->definitions[0].getTemp().type())
+ vectors[op.tempId()] = instr.get();
+ }
+ }
+
+ /* add operands to live variables */
+ for (const Operand& op : instr->operands) {
+ if (op.isTemp())
+ live.emplace(op.getTemp());
+ }
+
+ /* erase definitions from live */
+ for (unsigned i = 0; i < instr->definitions.size(); i++) {
+ const Definition& def = instr->definitions[i];
+ if (!def.isTemp())
+ continue;
+ live.erase(def.getTemp());
+ /* mark last-seen phi operand */
+ std::map<unsigned, unsigned>::iterator it = temp_to_phi_ressources.find(def.tempId());
+ if (it != temp_to_phi_ressources.end() && def.regClass() == phi_ressources[it->second][0].regClass()) {
+ phi_ressources[it->second][0] = def.getTemp();
+ /* try to coalesce phi affinities with parallelcopies */
+ if (!def.isFixed() && instr->opcode == aco_opcode::p_parallelcopy) {
+ Operand op = instr->operands[i];
+ if (op.isTemp() && op.isFirstKill() && def.regClass() == op.regClass()) {
+ phi_ressources[it->second].emplace_back(op.getTemp());
+ temp_to_phi_ressources[op.tempId()] = it->second;
+ }
+ }
}
}
}