diff options
author | Daniel Schürmann <daniel@schuermann.dev> | 2021-02-04 15:55:23 +0100 |
---|---|---|
committer | Marge Bot <eric+marge@anholt.net> | 2021-02-12 22:41:31 +0000 |
commit | 5d7b3bf1a73da8ae45bee61b173beac5a87c2c94 (patch) | |
tree | cefcc4f347e2590269b639f40052d84d33fc0324 | |
parent | e663a15098f8a028df413e0d2de0247c5f5991ea (diff) |
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@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8870>
-rw-r--r-- | src/amd/compiler/aco_live_var_analysis.cpp | 8 | ||||
-rw-r--r-- | src/amd/compiler/aco_lower_to_cssa.cpp | 7 | ||||
-rw-r--r-- | src/amd/compiler/aco_spill.cpp | 10 | ||||
-rw-r--r-- | 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; |