aco/spill: don't remove spilled phis

They will be removed during register allocation.

Few changes due to different phi order.
Totals from 14 (0.02% of 79395) affected shaders: (GFX11)

Instrs: 315724 -> 315675 (-0.02%); split: -0.02%, +0.01%
CodeSize: 1673608 -> 1673268 (-0.02%); split: -0.03%, +0.00%
Latency: 3194243 -> 3189025 (-0.16%); split: -0.19%, +0.03%
InvThroughput: 638369 -> 637323 (-0.16%); split: -0.19%, +0.03%
VClause: 5716 -> 5714 (-0.03%)
Copies: 37786 -> 37748 (-0.10%); split: -0.13%, +0.03%
Branches: 10469 -> 10454 (-0.14%); split: -0.16%, +0.02%
VALU: 182498 -> 182454 (-0.02%); split: -0.03%, +0.00%
SALU: 36038 -> 36046 (+0.02%); split: -0.01%, +0.04%
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29804>
This commit is contained in:
Daniel Schürmann
2024-06-20 12:36:05 +02:00
committed by Marge Bot
parent 634051f913
commit c4a38c6583

View File

@@ -602,12 +602,10 @@ add_coupling_code(spill_ctx& ctx, Block* block, IDSet& live_in)
ctx.ssa_infos[op.tempId()].num_uses--;
}
/* if the phi is not spilled, add to instructions */
/* The phi is not spilled */
if (!phi->definitions[0].isTemp() ||
!ctx.spills_entry[block_idx].count(phi->definitions[0].getTemp())) {
instructions.emplace_back(std::move(phi));
!ctx.spills_entry[block_idx].count(phi->definitions[0].getTemp()))
continue;
}
Block::edge_vec& preds =
phi->opcode == aco_opcode::p_phi ? block->logical_preds : block->linear_preds;
@@ -619,10 +617,11 @@ add_coupling_code(spill_ctx& ctx, Block* block, IDSet& live_in)
unsigned pred_idx = preds[i];
Operand spill_op = phi->operands[i];
phi->operands[i] = Operand(phi->definitions[0].regClass());
if (spill_op.isTemp()) {
assert(phi->operands[i].isKill());
Temp var = phi->operands[i].getTemp();
assert(spill_op.isKill());
Temp var = spill_op.getTemp();
std::map<Temp, Temp>::iterator rename_it = ctx.renames[pred_idx].find(var);
/* prevent the defining instruction from being DCE'd if it could be rematerialized */
@@ -637,6 +636,13 @@ add_coupling_code(spill_ctx& ctx, Block* block, IDSet& live_in)
continue;
}
/* If the phi operand has the same name as the definition,
* add to predecessor's spilled variables, so that it gets
* skipped in the loop below.
*/
if (var == phi->definitions[0].getTemp())
ctx.spills_exit[pred_idx][var] = def_spill_id;
/* rename if necessary */
if (rename_it != ctx.renames[pred_idx].end()) {
spill_op.setTemp(rename_it->second);
@@ -660,17 +666,7 @@ add_coupling_code(spill_ctx& ctx, Block* block, IDSet& live_in)
pred.instructions[idx]->opcode != aco_opcode::p_logical_end);
std::vector<aco_ptr<Instruction>>::iterator it = std::next(pred.instructions.begin(), idx);
pred.instructions.insert(it, std::move(spill));
/* If the phi operand has the same name as the definition,
* add to predecessor's spilled variables, so that it gets
* skipped in the loop below.
*/
if (spill_op.isTemp() && phi->operands[i].getTemp() == phi->definitions[0].getTemp())
ctx.spills_exit[pred_idx][phi->operands[i].getTemp()] = def_spill_id;
}
/* remove phi from instructions */
phi.reset();
}
/* iterate all (other) spilled variables for which to spill at the predecessor */
@@ -733,10 +729,14 @@ add_coupling_code(spill_ctx& ctx, Block* block, IDSet& live_in)
}
/* iterate phis for which operands to reload */
for (aco_ptr<Instruction>& phi : instructions) {
assert(phi->opcode == aco_opcode::p_phi || phi->opcode == aco_opcode::p_linear_phi);
for (aco_ptr<Instruction>& phi : block->instructions) {
if (!is_phi(phi))
break;
assert(!phi->definitions[0].isTemp() ||
!ctx.spills_entry[block_idx].count(phi->definitions[0].getTemp()));
!ctx.spills_entry[block_idx].count(phi->definitions[0].getTemp()) ||
std::all_of(phi->operands.begin(), phi->operands.end(),
[](Operand op) { return op.isUndefined(); }));
Block::edge_vec& preds =
phi->opcode == aco_opcode::p_phi ? block->logical_preds : block->linear_preds;
@@ -872,33 +872,15 @@ add_coupling_code(spill_ctx& ctx, Block* block, IDSet& live_in)
phi->operands[i] = Operand(tmp);
}
phi->definitions[0] = Definition(rename);
instructions.emplace_back(std::move(phi));
block->instructions.insert(block->instructions.begin(), std::move(phi));
ctx.program->live.register_demand[block->index].insert(
ctx.program->live.register_demand[block->index].begin(), block->live_in_demand);
}
/* the variable was renamed: add new name to renames */
if (!(rename == Temp() || rename == var))
ctx.renames[block_idx][var] = rename;
}
/* combine phis with instructions */
unsigned idx = 0;
while (!block->instructions[idx]) {
idx++;
}
if (!ctx.processed[block_idx]) {
assert(!(block->kind & block_kind_loop_header));
std::vector<RegisterDemand>& register_demand =
ctx.program->live.register_demand[block->index];
register_demand.erase(register_demand.begin(), register_demand.begin() + idx);
register_demand.insert(register_demand.begin(), instructions.size(), block->live_in_demand);
}
std::vector<aco_ptr<Instruction>>::iterator start = std::next(block->instructions.begin(), idx);
instructions.insert(
instructions.end(), std::move_iterator<std::vector<aco_ptr<Instruction>>::iterator>(start),
std::move_iterator<std::vector<aco_ptr<Instruction>>::iterator>(block->instructions.end()));
block->instructions = std::move(instructions);
}
void