aco: move some register demand helpers into aco_live_var_analysis.cpp
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/3914>
This commit is contained in:
parent
e1b08b55ff
commit
c51348bd9b
|
@ -1265,6 +1265,11 @@ void perfwarn(bool cond, const char *msg, Instruction *instr=NULL);
|
||||||
void aco_print_instr(Instruction *instr, FILE *output);
|
void aco_print_instr(Instruction *instr, FILE *output);
|
||||||
void aco_print_program(Program *program, FILE *output);
|
void aco_print_program(Program *program, FILE *output);
|
||||||
|
|
||||||
|
/* utilities for dealing with register demand */
|
||||||
|
RegisterDemand get_live_changes(aco_ptr<Instruction>& instr);
|
||||||
|
RegisterDemand get_temp_registers(aco_ptr<Instruction>& instr);
|
||||||
|
RegisterDemand get_demand_before(RegisterDemand demand, aco_ptr<Instruction>& instr, aco_ptr<Instruction>& instr_before);
|
||||||
|
|
||||||
/* number of sgprs that need to be allocated but might notbe addressable as s0-s105 */
|
/* number of sgprs that need to be allocated but might notbe addressable as s0-s105 */
|
||||||
uint16_t get_extra_sgprs(Program *program);
|
uint16_t get_extra_sgprs(Program *program);
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,46 @@
|
||||||
#include "vulkan/radv_shader.h"
|
#include "vulkan/radv_shader.h"
|
||||||
|
|
||||||
namespace aco {
|
namespace aco {
|
||||||
namespace {
|
RegisterDemand get_live_changes(aco_ptr<Instruction>& instr)
|
||||||
|
{
|
||||||
|
RegisterDemand changes;
|
||||||
|
for (const Definition& def : instr->definitions) {
|
||||||
|
if (!def.isTemp() || def.isKill())
|
||||||
|
continue;
|
||||||
|
changes += def.getTemp();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const Operand& op : instr->operands) {
|
||||||
|
if (!op.isTemp() || !op.isFirstKill())
|
||||||
|
continue;
|
||||||
|
changes -= op.getTemp();
|
||||||
|
}
|
||||||
|
|
||||||
|
return changes;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegisterDemand get_temp_registers(aco_ptr<Instruction>& instr)
|
||||||
|
{
|
||||||
|
RegisterDemand temp_registers;
|
||||||
|
for (Definition def : instr->definitions) {
|
||||||
|
if (!def.isTemp())
|
||||||
|
continue;
|
||||||
|
if (def.isKill())
|
||||||
|
temp_registers += def.getTemp();
|
||||||
|
}
|
||||||
|
return temp_registers;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegisterDemand get_demand_before(RegisterDemand demand, aco_ptr<Instruction>& instr, aco_ptr<Instruction>& instr_before)
|
||||||
|
{
|
||||||
|
demand -= get_live_changes(instr);
|
||||||
|
demand -= get_temp_registers(instr);
|
||||||
|
if (instr_before)
|
||||||
|
demand += get_temp_registers(instr_before);
|
||||||
|
return demand;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
void process_live_temps_per_block(Program *program, live& lives, Block* block,
|
void process_live_temps_per_block(Program *program, live& lives, Block* block,
|
||||||
std::set<unsigned>& worklist, std::vector<uint16_t>& phi_sgpr_ops)
|
std::set<unsigned>& worklist, std::vector<uint16_t>& phi_sgpr_ops)
|
||||||
{
|
{
|
||||||
|
@ -101,7 +139,6 @@ void process_live_temps_per_block(Program *program, live& lives, Block* block,
|
||||||
new_demand -= temp;
|
new_demand -= temp;
|
||||||
definition.setKill(false);
|
definition.setKill(false);
|
||||||
} else {
|
} else {
|
||||||
register_demand[idx] += temp;
|
|
||||||
definition.setKill(true);
|
definition.setKill(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,6 +183,8 @@ void process_live_temps_per_block(Program *program, live& lives, Block* block,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
register_demand[idx] += get_temp_registers(block->instructions[idx]);
|
||||||
|
|
||||||
block->register_demand.update(register_demand[idx]);
|
block->register_demand.update(register_demand[idx]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,35 +113,6 @@ void move_element(T begin_it, size_t idx, size_t before) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static RegisterDemand getLiveChanges(aco_ptr<Instruction>& instr)
|
|
||||||
{
|
|
||||||
RegisterDemand changes;
|
|
||||||
for (const Definition& def : instr->definitions) {
|
|
||||||
if (!def.isTemp() || def.isKill())
|
|
||||||
continue;
|
|
||||||
changes += def.getTemp();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const Operand& op : instr->operands) {
|
|
||||||
if (!op.isTemp() || !op.isFirstKill())
|
|
||||||
continue;
|
|
||||||
changes -= op.getTemp();
|
|
||||||
}
|
|
||||||
|
|
||||||
return changes;
|
|
||||||
}
|
|
||||||
|
|
||||||
static RegisterDemand getTempRegisters(aco_ptr<Instruction>& instr)
|
|
||||||
{
|
|
||||||
RegisterDemand temp_registers;
|
|
||||||
for (const Definition& def : instr->definitions) {
|
|
||||||
if (!def.isTemp() || !def.isKill())
|
|
||||||
continue;
|
|
||||||
temp_registers += def.getTemp();
|
|
||||||
}
|
|
||||||
return temp_registers;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MoveState::downwards_advance_helper()
|
void MoveState::downwards_advance_helper()
|
||||||
{
|
{
|
||||||
source_idx--;
|
source_idx--;
|
||||||
|
@ -207,11 +178,11 @@ MoveResult MoveState::downwards_move(bool clause)
|
||||||
int dest_insert_idx = clause ? insert_idx_clause : insert_idx;
|
int dest_insert_idx = clause ? insert_idx_clause : insert_idx;
|
||||||
RegisterDemand register_pressure = clause ? total_demand_clause : total_demand;
|
RegisterDemand register_pressure = clause ? total_demand_clause : total_demand;
|
||||||
|
|
||||||
const RegisterDemand candidate_diff = getLiveChanges(instr);
|
const RegisterDemand candidate_diff = get_live_changes(instr);
|
||||||
const RegisterDemand temp = getTempRegisters(instr);
|
const RegisterDemand temp = get_temp_registers(instr);
|
||||||
if (RegisterDemand(register_pressure - candidate_diff).exceeds(max_registers))
|
if (RegisterDemand(register_pressure - candidate_diff).exceeds(max_registers))
|
||||||
return move_fail_pressure;
|
return move_fail_pressure;
|
||||||
const RegisterDemand temp2 = getTempRegisters(block->instructions[dest_insert_idx - 1]);
|
const RegisterDemand temp2 = get_temp_registers(block->instructions[dest_insert_idx - 1]);
|
||||||
const RegisterDemand new_demand = register_demand[dest_insert_idx - 1] - temp2 + temp;
|
const RegisterDemand new_demand = register_demand[dest_insert_idx - 1] - temp2 + temp;
|
||||||
if (new_demand.exceeds(max_registers))
|
if (new_demand.exceeds(max_registers))
|
||||||
return move_fail_pressure;
|
return move_fail_pressure;
|
||||||
|
@ -302,11 +273,11 @@ MoveResult MoveState::upwards_move()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if register pressure is low enough: the diff is negative if register pressure is decreased */
|
/* check if register pressure is low enough: the diff is negative if register pressure is decreased */
|
||||||
const RegisterDemand candidate_diff = getLiveChanges(instr);
|
const RegisterDemand candidate_diff = get_live_changes(instr);
|
||||||
const RegisterDemand temp = getTempRegisters(instr);
|
const RegisterDemand temp = get_temp_registers(instr);
|
||||||
if (RegisterDemand(total_demand + candidate_diff).exceeds(max_registers))
|
if (RegisterDemand(total_demand + candidate_diff).exceeds(max_registers))
|
||||||
return move_fail_pressure;
|
return move_fail_pressure;
|
||||||
const RegisterDemand temp2 = getTempRegisters(block->instructions[insert_idx - 1]);
|
const RegisterDemand temp2 = get_temp_registers(block->instructions[insert_idx - 1]);
|
||||||
const RegisterDemand new_demand = register_demand[insert_idx - 1] - temp2 + candidate_diff + temp;
|
const RegisterDemand new_demand = register_demand[insert_idx - 1] - temp2 + candidate_diff + temp;
|
||||||
if (new_demand.exceeds(max_registers))
|
if (new_demand.exceeds(max_registers))
|
||||||
return move_fail_pressure;
|
return move_fail_pressure;
|
||||||
|
|
|
@ -660,15 +660,10 @@ RegisterDemand init_live_in_vars(spill_ctx& ctx, Block* block, unsigned block_id
|
||||||
RegisterDemand get_demand_before(spill_ctx& ctx, unsigned block_idx, unsigned idx)
|
RegisterDemand get_demand_before(spill_ctx& ctx, unsigned block_idx, unsigned idx)
|
||||||
{
|
{
|
||||||
if (idx == 0) {
|
if (idx == 0) {
|
||||||
RegisterDemand demand_before = ctx.register_demand[block_idx][idx];
|
RegisterDemand demand = ctx.register_demand[block_idx][idx];
|
||||||
aco_ptr<Instruction>& instr = ctx.program->blocks[block_idx].instructions[idx];
|
aco_ptr<Instruction>& instr = ctx.program->blocks[block_idx].instructions[idx];
|
||||||
for (const Definition& def : instr->definitions)
|
aco_ptr<Instruction> instr_before(nullptr);
|
||||||
demand_before -= def.getTemp();
|
return get_demand_before(demand, instr, instr_before);
|
||||||
for (const Operand& op : instr->operands) {
|
|
||||||
if (op.isFirstKill())
|
|
||||||
demand_before += op.getTemp();
|
|
||||||
}
|
|
||||||
return demand_before;
|
|
||||||
} else {
|
} else {
|
||||||
return ctx.register_demand[block_idx][idx - 1];
|
return ctx.register_demand[block_idx][idx - 1];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue