From fab911858c8575c50e90389f21ed5c92f846bda4 Mon Sep 17 00:00:00 2001 From: Rhys Perry Date: Wed, 12 Apr 2023 16:00:10 +0100 Subject: [PATCH] aco: consider how definitions fixed to operands can change register demand MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Usually the register demand before an instruction would be considered part of the previous instruction, since it's not greater than the register demand for that previous instruction. Except, it can be greater in the case of an definition fixed to a non-killed operand: the RA needs to reserve space between the two instructions for the definition (containing a copy of the operand). fossil-db (navi21): Totals from 5 (0.00% of 135636) affected shaders: PreVGPRs: 35 -> 40 (+14.29%) Signed-off-by: Rhys Perry Reviewed-by: Daniel Schürmann Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/8807 Part-of: --- src/amd/compiler/aco_live_var_analysis.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/amd/compiler/aco_live_var_analysis.cpp b/src/amd/compiler/aco_live_var_analysis.cpp index bedc829..b912218 100644 --- a/src/amd/compiler/aco_live_var_analysis.cpp +++ b/src/amd/compiler/aco_live_var_analysis.cpp @@ -50,6 +50,20 @@ get_live_changes(aco_ptr& instr) return changes; } +void +handle_def_fixed_to_op(RegisterDemand* demand, RegisterDemand demand_before, Instruction* instr, + int op_idx) +{ + /* Usually the register demand before an instruction would be considered part of the previous + * instruction, since it's not greater than the register demand for that previous instruction. + * Except, it can be greater in the case of an definition fixed to a non-killed operand: the RA + * needs to reserve space between the two instructions for the definition (containing a copy of + * the operand). + */ + demand_before += instr->definitions[0].getTemp(); + demand->update(demand_before); +} + RegisterDemand get_temp_registers(aco_ptr& instr) { @@ -67,6 +81,13 @@ get_temp_registers(aco_ptr& instr) temp_registers += op.getTemp(); } + int op_idx = get_op_fixed_to_def(instr.get()); + if (op_idx != -1 && !instr->operands[op_idx].isKill()) { + RegisterDemand before_instr; + before_instr -= get_live_changes(instr); + handle_def_fixed_to_op(&temp_registers, before_instr, instr.get(), op_idx); + } + return temp_registers; } @@ -183,6 +204,12 @@ process_live_temps_per_block(Program* program, live& lives, Block* block, unsign } } + int op_idx = get_op_fixed_to_def(insn); + if (op_idx != -1 && !insn->operands[op_idx].isKill()) { + RegisterDemand before_instr = new_demand; + handle_def_fixed_to_op(®ister_demand[idx], before_instr, insn, op_idx); + } + block_register_demand.update(register_demand[idx]); } -- 2.7.4