Mesa (main): aco: use std::vector and IDSet in RA validator

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Oct 28 09:18:06 UTC 2021


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

Author: Rhys Perry <pendingchaos02 at gmail.com>
Date:   Wed Oct 27 09:34:44 2021 +0100

aco: use std::vector and IDSet in RA validator

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/13541>

---

 src/amd/compiler/aco_validate.cpp | 56 +++++++++++++++++++++------------------
 1 file changed, 30 insertions(+), 26 deletions(-)

diff --git a/src/amd/compiler/aco_validate.cpp b/src/amd/compiler/aco_validate.cpp
index 0badb3ce17a..8c5a84ac3f9 100644
--- a/src/amd/compiler/aco_validate.cpp
+++ b/src/amd/compiler/aco_validate.cpp
@@ -670,6 +670,7 @@ struct Assignment {
    Location defloc;
    Location firstloc;
    PhysReg reg;
+   bool valid;
 };
 
 bool
@@ -849,7 +850,7 @@ validate_ra(Program* program)
    std::vector<std::vector<Temp>> phi_sgpr_ops(program->blocks.size());
    uint16_t sgpr_limit = get_addr_sgpr_from_waves(program, program->num_waves);
 
-   std::map<unsigned, Assignment> assignments;
+   std::vector<Assignment> assignments(program->peekAllocationId());
    for (Block& block : program->blocks) {
       Location loc;
       loc.block = █
@@ -870,16 +871,16 @@ validate_ra(Program* program)
                continue;
             if (!op.isFixed())
                err |= ra_fail(program, loc, Location(), "Operand %d is not assigned a register", i);
-            if (assignments.count(op.tempId()) && assignments[op.tempId()].reg != op.physReg())
+            if (assignments[op.tempId()].valid && assignments[op.tempId()].reg != op.physReg())
                err |=
-                  ra_fail(program, loc, assignments.at(op.tempId()).firstloc,
+                  ra_fail(program, loc, assignments[op.tempId()].firstloc,
                           "Operand %d has an inconsistent register assignment with instruction", i);
             if ((op.getTemp().type() == RegType::vgpr &&
                  op.physReg().reg_b + op.bytes() > (256 + program->config->num_vgprs) * 4) ||
                 (op.getTemp().type() == RegType::sgpr &&
                  op.physReg() + op.size() > program->config->num_sgprs &&
                  op.physReg() < sgpr_limit))
-               err |= ra_fail(program, loc, assignments.at(op.tempId()).firstloc,
+               err |= ra_fail(program, loc, assignments[op.tempId()].firstloc,
                               "Operand %d has an out-of-bounds register assignment", i);
             if (op.physReg() == vcc && !program->needs_vcc)
                err |= ra_fail(program, loc, Location(),
@@ -889,8 +890,10 @@ validate_ra(Program* program)
                err |= ra_fail(program, loc, Location(), "Operand %d not aligned correctly", i);
             if (!assignments[op.tempId()].firstloc.block)
                assignments[op.tempId()].firstloc = loc;
-            if (!assignments[op.tempId()].defloc.block)
+            if (!assignments[op.tempId()].defloc.block) {
                assignments[op.tempId()].reg = op.physReg();
+               assignments[op.tempId()].valid = true;
+            }
          }
 
          for (unsigned i = 0; i < instr->definitions.size(); i++) {
@@ -901,14 +904,14 @@ validate_ra(Program* program)
                err |=
                   ra_fail(program, loc, Location(), "Definition %d is not assigned a register", i);
             if (assignments[def.tempId()].defloc.block)
-               err |= ra_fail(program, loc, assignments.at(def.tempId()).defloc,
+               err |= ra_fail(program, loc, assignments[def.tempId()].defloc,
                               "Temporary %%%d also defined by instruction", def.tempId());
             if ((def.getTemp().type() == RegType::vgpr &&
                  def.physReg().reg_b + def.bytes() > (256 + program->config->num_vgprs) * 4) ||
                 (def.getTemp().type() == RegType::sgpr &&
                  def.physReg() + def.size() > program->config->num_sgprs &&
                  def.physReg() < sgpr_limit))
-               err |= ra_fail(program, loc, assignments.at(def.tempId()).firstloc,
+               err |= ra_fail(program, loc, assignments[def.tempId()].firstloc,
                               "Definition %d has an out-of-bounds register assignment", i);
             if (def.physReg() == vcc && !program->needs_vcc)
                err |= ra_fail(program, loc, Location(),
@@ -920,6 +923,7 @@ validate_ra(Program* program)
                assignments[def.tempId()].firstloc = loc;
             assignments[def.tempId()].defloc = loc;
             assignments[def.tempId()].reg = def.physReg();
+            assignments[def.tempId()].valid = true;
          }
       }
    }
@@ -931,23 +935,22 @@ validate_ra(Program* program)
       std::array<unsigned, 2048> regs; /* register file in bytes */
       regs.fill(0);
 
-      std::set<Temp> live;
-      for (unsigned id : live_vars.live_out[block.index])
-         live.insert(Temp(id, program->temp_rc[id]));
+      IDSet live = live_vars.live_out[block.index];
       /* remove killed p_phi sgpr operands */
       for (Temp tmp : phi_sgpr_ops[block.index])
-         live.erase(tmp);
+         live.erase(tmp.id());
 
       /* check live out */
-      for (Temp tmp : live) {
-         PhysReg reg = assignments.at(tmp.id()).reg;
+      for (unsigned id : live) {
+         Temp tmp(id, program->temp_rc[id]);
+         PhysReg reg = assignments[id].reg;
          for (unsigned i = 0; i < tmp.bytes(); i++) {
             if (regs[reg.reg_b + i]) {
                err |= ra_fail(program, loc, Location(),
                               "Assignment of element %d of %%%d already taken by %%%d in live-out",
-                              i, tmp.id(), regs[reg.reg_b + i]);
+                              i, id, regs[reg.reg_b + i]);
             }
-            regs[reg.reg_b + i] = tmp.id();
+            regs[reg.reg_b + i] = id;
          }
       }
       regs.fill(0);
@@ -958,7 +961,7 @@ validate_ra(Program* program)
          /* check killed p_phi sgpr operands */
          if (instr->opcode == aco_opcode::p_logical_end) {
             for (Temp tmp : phi_sgpr_ops[block.index]) {
-               PhysReg reg = assignments.at(tmp.id()).reg;
+               PhysReg reg = assignments[tmp.id()].reg;
                for (unsigned i = 0; i < tmp.bytes(); i++) {
                   if (regs[reg.reg_b + i])
                      err |= ra_fail(
@@ -966,14 +969,14 @@ validate_ra(Program* program)
                         "Assignment of element %d of %%%d already taken by %%%d in live-out", i,
                         tmp.id(), regs[reg.reg_b + i]);
                }
-               live.emplace(tmp);
+               live.insert(tmp.id());
             }
          }
 
          for (const Definition& def : instr->definitions) {
             if (!def.isTemp())
                continue;
-            live.erase(def.getTemp());
+            live.erase(def.tempId());
          }
 
          /* don't count phi operands as live-in, since they are actually
@@ -982,15 +985,16 @@ validate_ra(Program* program)
             for (const Operand& op : instr->operands) {
                if (!op.isTemp())
                   continue;
-               live.insert(op.getTemp());
+               live.insert(op.tempId());
             }
          }
       }
 
-      for (Temp tmp : live) {
-         PhysReg reg = assignments.at(tmp.id()).reg;
+      for (unsigned id : live) {
+         Temp tmp(id, program->temp_rc[id]);
+         PhysReg reg = assignments[id].reg;
          for (unsigned i = 0; i < tmp.bytes(); i++)
-            regs[reg.reg_b + i] = tmp.id();
+            regs[reg.reg_b + i] = id;
       }
 
       for (aco_ptr<Instruction>& instr : block.instructions) {
@@ -999,7 +1003,7 @@ validate_ra(Program* program)
          /* remove killed p_phi operands from regs */
          if (instr->opcode == aco_opcode::p_logical_end) {
             for (Temp tmp : phi_sgpr_ops[block.index]) {
-               PhysReg reg = assignments.at(tmp.id()).reg;
+               PhysReg reg = assignments[tmp.id()].reg;
                for (unsigned i = 0; i < tmp.bytes(); i++)
                   regs[reg.reg_b + i] = 0;
             }
@@ -1021,11 +1025,11 @@ validate_ra(Program* program)
             if (!def.isTemp())
                continue;
             Temp tmp = def.getTemp();
-            PhysReg reg = assignments.at(tmp.id()).reg;
+            PhysReg reg = assignments[tmp.id()].reg;
             for (unsigned j = 0; j < tmp.bytes(); j++) {
                if (regs[reg.reg_b + j])
                   err |= ra_fail(
-                     program, loc, assignments.at(regs[reg.reg_b + j]).defloc,
+                     program, loc, assignments[regs[reg.reg_b + j]].defloc,
                      "Assignment of element %d of %%%d already taken by %%%d from instruction", i,
                      tmp.id(), regs[reg.reg_b + j]);
                regs[reg.reg_b + j] = tmp.id();
@@ -1037,7 +1041,7 @@ validate_ra(Program* program)
                for (unsigned j = reg.byte() & ~(written - 1); j < written; j++) {
                   unsigned written_reg = reg.reg() * 4u + j;
                   if (regs[written_reg] && regs[written_reg] != def.tempId())
-                     err |= ra_fail(program, loc, assignments.at(regs[written_reg]).defloc,
+                     err |= ra_fail(program, loc, assignments[regs[written_reg]].defloc,
                                     "Assignment of element %d of %%%d overwrites the full register "
                                     "taken by %%%d from instruction",
                                     i, tmp.id(), regs[written_reg]);



More information about the mesa-commit mailing list