Mesa (master): aco: add affinity for non-sequential MIMG operands

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Jan 20 17:00:54 UTC 2021


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

Author: Rhys Perry <pendingchaos02 at gmail.com>
Date:   Wed Dec  9 16:32:58 2020 +0000

aco: add affinity for non-sequential MIMG operands

fossil-db (GFX10.3):
Totals from 42008 (30.14% of 139391) affected shaders:
VGPRs: 2139116 -> 2147696 (+0.40%); split: -0.06%, +0.46%
CodeSize: 199109120 -> 198637852 (-0.24%); split: -0.24%, +0.01%
Instrs: 37713901 -> 37714574 (+0.00%); split: -0.02%, +0.03%
Cycles: 1621911328 -> 1621634168 (-0.02%); split: -0.02%, +0.01%

Signed-off-by: Rhys Perry <pendingchaos02 at gmail.com>
Reviewed-by: Daniel Schürmann <daniel at schuermann.dev>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8523>

---

 src/amd/compiler/aco_register_allocation.cpp | 79 +++++++++++++++++++++-------
 1 file changed, 59 insertions(+), 20 deletions(-)

diff --git a/src/amd/compiler/aco_register_allocation.cpp b/src/amd/compiler/aco_register_allocation.cpp
index da1fa44fd61..8b59317c51b 100644
--- a/src/amd/compiler/aco_register_allocation.cpp
+++ b/src/amd/compiler/aco_register_allocation.cpp
@@ -1253,6 +1253,35 @@ void increase_register_file(ra_ctx& ctx, RegType type) {
    }
 }
 
+bool is_mimg_vaddr_intact(ra_ctx& ctx, RegisterFile& reg_file, Instruction *instr)
+{
+   PhysReg first{512};
+   for (unsigned i = 0; i < instr->operands.size() - 3u; i++) {
+      Operand op = instr->operands[i + 3];
+
+      if (ctx.assignments[op.tempId()].assigned) {
+         PhysReg reg = ctx.assignments[op.tempId()].reg;
+
+         if (first.reg() != 512 && reg != first.advance(i * 4))
+            return false; /* not at the best position */
+
+         if ((reg.reg() - 256) < i)
+            return false; /* no space for previous operands */
+
+         first = reg.advance(i * -4);
+      } else if (first.reg() != 512) {
+         /* If there's an unexpected temporary, this operand is unlikely to be
+          * placed in the best position.
+          */
+         unsigned id = reg_file.get_id(first.advance(i * 4));
+         if (id && id != op.tempId())
+            return false;
+      }
+   }
+
+   return true;
+}
+
 PhysReg get_reg(ra_ctx& ctx,
                 RegisterFile& reg_file,
                 Temp temp,
@@ -1284,35 +1313,42 @@ PhysReg get_reg(ra_ctx& ctx,
 
    if (ctx.vectors.find(temp.id()) != ctx.vectors.end()) {
       Instruction* vec = ctx.vectors[temp.id()];
+      unsigned first_operand = vec->format == Format::MIMG ? 3 : 0;
       unsigned byte_offset = 0;
-      for (const Operand& op : vec->operands) {
+      for (unsigned i = first_operand; i < vec->operands.size(); i++) {
+         Operand& op = vec->operands[i];
          if (op.isTemp() && op.tempId() == temp.id())
             break;
          else
             byte_offset += op.bytes();
       }
-      unsigned k = 0;
-      for (const Operand& op : vec->operands) {
-         if (op.isTemp() &&
-             op.tempId() != temp.id() &&
-             op.getTemp().type() == temp.type() &&
-             ctx.assignments[op.tempId()].assigned) {
-            PhysReg reg = ctx.assignments[op.tempId()].reg;
-            reg.reg_b += (byte_offset - k);
+
+      if (vec->format != Format::MIMG || is_mimg_vaddr_intact(ctx, reg_file, vec)) {
+         unsigned k = 0;
+         for (unsigned i = first_operand; i < vec->operands.size(); i++) {
+            Operand& op = vec->operands[i];
+            if (op.isTemp() &&
+                op.tempId() != temp.id() &&
+                op.getTemp().type() == temp.type() &&
+                ctx.assignments[op.tempId()].assigned) {
+               PhysReg reg = ctx.assignments[op.tempId()].reg;
+               reg.reg_b += (byte_offset - k);
+               if (get_reg_specified(ctx, reg_file, temp.regClass(), instr, reg))
+                  return reg;
+            }
+            k += op.bytes();
+         }
+
+         RegClass vec_rc = RegClass::get(temp.type(), k);
+         DefInfo info(ctx, ctx.pseudo_dummy, vec_rc, -1);
+         std::pair<PhysReg, bool> res = get_reg_simple(ctx, reg_file, info);
+         PhysReg reg = res.first;
+         if (res.second) {
+            reg.reg_b += byte_offset;
+            /* make sure to only use byte offset if the instruction supports it */
             if (get_reg_specified(ctx, reg_file, temp.regClass(), instr, reg))
                return reg;
          }
-         k += op.bytes();
-      }
-
-      DefInfo info(ctx, ctx.pseudo_dummy, vec->definitions[0].regClass(), -1);
-      std::pair<PhysReg, bool> res = get_reg_simple(ctx, reg_file, info);
-      PhysReg reg = res.first;
-      if (res.second) {
-         reg.reg_b += byte_offset;
-         /* make sure to only use byte offset if the instruction supports it */
-         if (get_reg_specified(ctx, reg_file, temp.regClass(), instr, reg))
-            return reg;
       }
    }
 
@@ -1830,6 +1866,9 @@ void register_allocation(Program *program, std::vector<IDSet>& live_out_per_bloc
                   if (op.isTemp() && op.isFirstKill() && op.getTemp().type() == instr->definitions[0].getTemp().type())
                      ctx.vectors[op.tempId()] = instr.get();
                }
+            } else if (instr->format == Format::MIMG && instr->operands.size() > 4) {
+               for (unsigned i = 3; i < instr->operands.size(); i++)
+                  ctx.vectors[instr->operands[i].tempId()] = instr.get();
             }
 
             if (instr->opcode == aco_opcode::p_split_vector && instr->operands[0].isFirstKillBeforeDef())



More information about the mesa-commit mailing list