aco: add validate_instr_defs()
authorRhys Perry <pendingchaos02@gmail.com>
Wed, 20 Oct 2021 08:11:51 +0000 (09:11 +0100)
committerMarge Bot <emma+marge@anholt.net>
Thu, 3 Mar 2022 20:21:08 +0000 (20:21 +0000)
Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Reviewed-by: Daniel Schürmann <daniel@schuermann.dev>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13432>

src/amd/compiler/aco_validate.cpp

index da6dc18..7df92a5 100644 (file)
@@ -902,6 +902,54 @@ get_subdword_bytes_written(Program* program, const aco_ptr<Instruction>& instr,
    }
 }
 
+bool
+validate_instr_defs(Program* program, std::array<unsigned, 2048>& regs,
+                    const std::vector<Assignment>& assignments, const Location& loc,
+                    aco_ptr<Instruction>& instr)
+{
+   bool err = false;
+
+   for (unsigned i = 0; i < instr->definitions.size(); i++) {
+      Definition& def = instr->definitions[i];
+      if (!def.isTemp())
+         continue;
+      Temp tmp = def.getTemp();
+      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[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();
+      }
+      if (def.regClass().is_subdword() && def.bytes() < 4) {
+         unsigned written = get_subdword_bytes_written(program, instr, i);
+         /* If written=4, the instruction still might write the upper half. In that case, it's
+          * the lower half that isn't preserved */
+         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[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]);
+         }
+      }
+   }
+
+   for (const Definition& def : instr->definitions) {
+      if (!def.isTemp())
+         continue;
+      if (def.isKill()) {
+         for (unsigned j = 0; j < def.getTemp().bytes(); j++)
+            regs[def.physReg().reg_b + j] = 0;
+      }
+   }
+
+   return err;
+}
+
 } /* end namespace */
 
 bool
@@ -1085,45 +1133,9 @@ validate_ra(Program* program)
             }
          }
 
-         for (unsigned i = 0; i < instr->definitions.size(); i++) {
-            Definition& def = instr->definitions[i];
-            if (!def.isTemp())
-               continue;
-            Temp tmp = def.getTemp();
-            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[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();
-            }
-            if (def.regClass().is_subdword() && def.bytes() < 4) {
-               unsigned written = get_subdword_bytes_written(program, instr, i);
-               /* If written=4, the instruction still might write the upper half. In that case, it's
-                * the lower half that isn't preserved */
-               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[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]);
-               }
-            }
-         }
+         err |= validate_instr_defs(program, regs, assignments, loc, instr);
 
-         for (const Definition& def : instr->definitions) {
-            if (!def.isTemp())
-               continue;
-            if (def.isKill()) {
-               for (unsigned j = 0; j < def.getTemp().bytes(); j++)
-                  regs[def.physReg().reg_b + j] = 0;
-            }
-         }
-
-         if (instr->opcode != aco_opcode::p_phi && instr->opcode != aco_opcode::p_linear_phi) {
+         if (!is_phi(instr)) {
             for (const Operand& op : instr->operands) {
                if (!op.isTemp())
                   continue;