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:

committed by
Marge Bot

parent
634051f913
commit
c4a38c6583
@@ -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
|
||||
|
Reference in New Issue
Block a user