Mesa (master): aco: handle non-temp phi definitions and operands

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Feb 12 23:24:27 UTC 2021


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

Author: Daniel Schürmann <daniel at schuermann.dev>
Date:   Thu Feb  4 15:55:23 2021 +0100

aco: handle non-temp phi definitions and operands

This will be necessary as we make exec non-temp.

No fossil-db changes.

Reviewed-by: Rhys Perry <pendingchaos02 at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8870>

---

 src/amd/compiler/aco_live_var_analysis.cpp |  8 ++++++--
 src/amd/compiler/aco_lower_to_cssa.cpp     |  7 +++++--
 src/amd/compiler/aco_spill.cpp             | 10 ++++++----
 src/amd/compiler/aco_ssa_elimination.cpp   |  2 +-
 4 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/src/amd/compiler/aco_live_var_analysis.cpp b/src/amd/compiler/aco_live_var_analysis.cpp
index 5812e7aebe9..81782cbbe4a 100644
--- a/src/amd/compiler/aco_live_var_analysis.cpp
+++ b/src/amd/compiler/aco_live_var_analysis.cpp
@@ -171,8 +171,12 @@ void process_live_temps_per_block(Program *program, live& lives, Block* block,
       register_demand[phi_idx] = new_demand;
       Instruction *insn = block->instructions[phi_idx].get();
 
-      assert(is_phi(insn));
-      assert(insn->definitions.size() == 1 && insn->definitions[0].isTemp());
+      assert(is_phi(insn) && insn->definitions.size() == 1);
+      if (!insn->definitions[0].isTemp()) {
+         assert(insn->definitions[0].isFixed() && insn->definitions[0].physReg() == exec);
+         phi_idx--;
+         continue;
+      }
       Definition& definition = insn->definitions[0];
       if ((definition.isFixed() || definition.hasHint()) && definition.physReg() == vcc)
          program->needs_vcc = true;
diff --git a/src/amd/compiler/aco_lower_to_cssa.cpp b/src/amd/compiler/aco_lower_to_cssa.cpp
index 4dba8aa2677..accfd48f498 100644
--- a/src/amd/compiler/aco_lower_to_cssa.cpp
+++ b/src/amd/compiler/aco_lower_to_cssa.cpp
@@ -77,8 +77,7 @@ bool collect_phi_info(cssa_ctx& ctx)
             } else if (op.isConstant()) {
                /* in theory, we could insert the definition there... */
                def_points[i] = 0;
-            } else {
-               assert(op.isTemp());
+            } else if (op.isTemp()) {
                unsigned pred = preds[i];
                do {
                   def_points[i] = pred;
@@ -87,6 +86,10 @@ bool collect_phi_info(cssa_ctx& ctx)
                          ctx.program->blocks[pred].linear_idom;
                } while (def_points[i] != pred &&
                         ctx.live_vars.live_out[pred].count(op.tempId()));
+            } else {
+               /* no need to insert a copy of the exec mask */
+               assert(op.isFixed() && op.physReg() == exec);
+               def_points[i] = preds[i];
             }
          }
 
diff --git a/src/amd/compiler/aco_spill.cpp b/src/amd/compiler/aco_spill.cpp
index 39c53ea8f19..2ea7265ca5a 100644
--- a/src/amd/compiler/aco_spill.cpp
+++ b/src/amd/compiler/aco_spill.cpp
@@ -607,9 +607,10 @@ RegisterDemand init_live_in_vars(spill_ctx& ctx, Block* block, unsigned block_id
       bool spill = true;
 
       for (unsigned i = 0; i < phi->operands.size(); i++) {
-         if (phi->operands[i].isUndefined())
+         assert(!phi->operands[i].isConstant());
+         // TODO: in theory, we can spill phis with exec operands and temp definitions
+         if (!phi->definitions[0].isTemp() || !phi->operands[i].isTemp())
             continue;
-         assert(phi->operands[i].isTemp());
          if (ctx.spills_exit[preds[i]].find(phi->operands[i].getTemp()) == ctx.spills_exit[preds[i]].end())
             spill = false;
          else
@@ -819,7 +820,8 @@ void add_coupling_code(spill_ctx& ctx, Block* block, unsigned block_idx)
          break;
 
       /* if the phi is not spilled, add to instructions */
-      if (ctx.spills_entry[block_idx].find(phi->definitions[0].getTemp()) == ctx.spills_entry[block_idx].end()) {
+      if (!phi->definitions[0].isTemp() ||
+          ctx.spills_entry[block_idx].find(phi->definitions[0].getTemp()) == ctx.spills_entry[block_idx].end()) {
          instructions.emplace_back(std::move(phi));
          continue;
       }
@@ -933,7 +935,7 @@ void add_coupling_code(spill_ctx& ctx, Block* block, unsigned block_idx)
    /* iterate phis for which operands to reload */
    for (aco_ptr<Instruction>& phi : instructions) {
       assert(phi->opcode == aco_opcode::p_phi || phi->opcode == aco_opcode::p_linear_phi);
-      assert(ctx.spills_entry[block_idx].find(phi->definitions[0].getTemp()) == ctx.spills_entry[block_idx].end());
+      assert(!phi->definitions[0].isTemp() || ctx.spills_entry[block_idx].find(phi->definitions[0].getTemp()) == ctx.spills_entry[block_idx].end());
 
       std::vector<unsigned>& preds = phi->opcode == aco_opcode::p_phi ? block->logical_preds : block->linear_preds;
       for (unsigned i = 0; i < phi->operands.size(); i++) {
diff --git a/src/amd/compiler/aco_ssa_elimination.cpp b/src/amd/compiler/aco_ssa_elimination.cpp
index 54f7405f6f1..057028486c8 100644
--- a/src/amd/compiler/aco_ssa_elimination.cpp
+++ b/src/amd/compiler/aco_ssa_elimination.cpp
@@ -52,7 +52,7 @@ void collect_phi_info(ssa_elimination_ctx& ctx)
          for (unsigned i = 0; i < phi->operands.size(); i++) {
             if (phi->operands[i].isUndefined())
                continue;
-            if (phi->operands[i].isTemp() && phi->operands[i].physReg() == phi->definitions[0].physReg())
+            if (phi->operands[i].physReg() == phi->definitions[0].physReg())
                continue;
 
             std::vector<unsigned>& preds = phi->opcode == aco_opcode::p_phi ? block.logical_preds : block.linear_preds;



More information about the mesa-commit mailing list