void aco_print_instr(Instruction *instr, 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 */
uint16_t get_extra_sgprs(Program *program);
#include "vulkan/radv_shader.h"
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,
std::set<unsigned>& worklist, std::vector<uint16_t>& phi_sgpr_ops)
{
new_demand -= temp;
definition.setKill(false);
} else {
- register_demand[idx] += temp;
definition.setKill(true);
}
}
}
+ register_demand[idx] += get_temp_registers(block->instructions[idx]);
+
block->register_demand.update(register_demand[idx]);
}
}
}
-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()
{
source_idx--;
int dest_insert_idx = clause ? insert_idx_clause : insert_idx;
RegisterDemand register_pressure = clause ? total_demand_clause : total_demand;
- const RegisterDemand candidate_diff = getLiveChanges(instr);
- const RegisterDemand temp = getTempRegisters(instr);
+ const RegisterDemand candidate_diff = get_live_changes(instr);
+ const RegisterDemand temp = get_temp_registers(instr);
if (RegisterDemand(register_pressure - candidate_diff).exceeds(max_registers))
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;
if (new_demand.exceeds(max_registers))
return move_fail_pressure;
}
/* check if register pressure is low enough: the diff is negative if register pressure is decreased */
- const RegisterDemand candidate_diff = getLiveChanges(instr);
- const RegisterDemand temp = getTempRegisters(instr);
+ const RegisterDemand candidate_diff = get_live_changes(instr);
+ const RegisterDemand temp = get_temp_registers(instr);
if (RegisterDemand(total_demand + candidate_diff).exceeds(max_registers))
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;
if (new_demand.exceeds(max_registers))
return move_fail_pressure;
RegisterDemand get_demand_before(spill_ctx& ctx, unsigned block_idx, unsigned idx)
{
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];
- for (const Definition& def : instr->definitions)
- demand_before -= def.getTemp();
- for (const Operand& op : instr->operands) {
- if (op.isFirstKill())
- demand_before += op.getTemp();
- }
- return demand_before;
+ aco_ptr<Instruction> instr_before(nullptr);
+ return get_demand_before(demand, instr, instr_before);
} else {
return ctx.register_demand[block_idx][idx - 1];
}