aco/spill: Reduce allocations in next_uses_per_block

Reviewed-by: Daniel Schürmann <daniel@schuermann.dev>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11925>
This commit is contained in:
Tony Wasserka 2021-07-15 17:11:24 +02:00 committed by Marge Bot
parent a6bcda6a01
commit a3ac3b231f
1 changed files with 17 additions and 13 deletions

View File

@ -171,13 +171,14 @@ void
next_uses_per_block(spill_ctx& ctx, unsigned block_idx, uint32_t& worklist)
{
Block* block = &ctx.program->blocks[block_idx];
std::unordered_map<Temp, std::pair<uint32_t, uint32_t>> next_uses =
ctx.next_use_distances_end[block_idx];
ctx.next_use_distances_start[block_idx] = ctx.next_use_distances_end[block_idx];
auto& next_use_distances_start = ctx.next_use_distances_start[block_idx];
/* to compute the next use distance at the beginning of the block, we have to add the block's
* size */
for (std::unordered_map<Temp, std::pair<uint32_t, uint32_t>>::iterator it = next_uses.begin();
it != next_uses.end(); ++it)
for (std::unordered_map<Temp, std::pair<uint32_t, uint32_t>>::iterator it =
next_use_distances_start.begin();
it != next_use_distances_start.end(); ++it)
it->second.second = it->second.second + block->instructions.size();
int idx = block->instructions.size() - 1;
@ -189,7 +190,7 @@ next_uses_per_block(spill_ctx& ctx, unsigned block_idx, uint32_t& worklist)
for (const Definition& def : instr->definitions) {
if (def.isTemp())
next_uses.erase(def.getTemp());
next_use_distances_start.erase(def.getTemp());
}
for (const Operand& op : instr->operands) {
@ -199,24 +200,24 @@ next_uses_per_block(spill_ctx& ctx, unsigned block_idx, uint32_t& worklist)
if (op.regClass().type() == RegType::vgpr && op.regClass().is_linear())
continue;
if (op.isTemp())
next_uses[op.getTemp()] = {block_idx, idx};
next_use_distances_start[op.getTemp()] = {block_idx, idx};
}
idx--;
}
assert(block_idx != 0 || next_uses.empty());
ctx.next_use_distances_start[block_idx] = next_uses;
assert(block_idx != 0 || next_use_distances_start.empty());
std::unordered_set<Temp> phi_defs;
while (idx >= 0) {
aco_ptr<Instruction>& instr = block->instructions[idx];
assert(instr->opcode == aco_opcode::p_linear_phi || instr->opcode == aco_opcode::p_phi);
std::pair<uint32_t, uint32_t> distance{block_idx, 0};
auto it = instr->definitions[0].isTemp() ? next_uses.find(instr->definitions[0].getTemp())
: next_uses.end();
if (it != next_uses.end()) {
auto it = instr->definitions[0].isTemp() ? next_use_distances_start.find(instr->definitions[0].getTemp())
: next_use_distances_start.end();
if (it != next_use_distances_start.end() &&
phi_defs.insert(instr->definitions[0].getTemp()).second) {
distance = it->second;
next_uses.erase(it);
}
for (unsigned i = 0; i < instr->operands.size(); i++) {
@ -236,8 +237,11 @@ next_uses_per_block(spill_ctx& ctx, unsigned block_idx, uint32_t& worklist)
}
/* all remaining live vars must be live-out at the predecessors */
for (std::pair<const Temp, std::pair<uint32_t, uint32_t>>& pair : next_uses) {
for (std::pair<const Temp, std::pair<uint32_t, uint32_t>>& pair : next_use_distances_start) {
Temp temp = pair.first;
if (phi_defs.count(temp)) {
continue;
}
uint32_t distance = pair.second.second;
uint32_t dom = pair.second.first;
std::vector<unsigned>& preds = temp.is_linear() ? block->linear_preds : block->logical_preds;