Mesa (main): aco/spill: Reduce allocations in next_uses_per_block

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Oct 1 09:57:12 UTC 2021


Module: Mesa
Branch: main
Commit: a3ac3b231fdab9f2c0c47914719612f3345b42c5
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=a3ac3b231fdab9f2c0c47914719612f3345b42c5

Author: Tony Wasserka <tony.wasserka at gmx.de>
Date:   Thu Jul 15 17:11:24 2021 +0200

aco/spill: Reduce allocations in next_uses_per_block

Reviewed-by: Daniel Schürmann <daniel at schuermann.dev>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11925>

---

 src/amd/compiler/aco_spill.cpp | 30 +++++++++++++++++-------------
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/src/amd/compiler/aco_spill.cpp b/src/amd/compiler/aco_spill.cpp
index bf4c8c9da0d..c52004c4a86 100644
--- a/src/amd/compiler/aco_spill.cpp
+++ b/src/amd/compiler/aco_spill.cpp
@@ -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;



More information about the mesa-commit mailing list