aco: use std::vector and IDSet in RA validator

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/13541>
This commit is contained in:
Rhys Perry 2021-10-27 09:34:44 +01:00 committed by Marge Bot
parent b42f4b8809
commit 11602d2d36

View file

@ -670,6 +670,7 @@ struct Assignment {
Location defloc;
Location firstloc;
PhysReg reg;
bool valid;
};
bool
@ -849,7 +850,7 @@ validate_ra(Program* program)
std::vector<std::vector<Temp>> phi_sgpr_ops(program->blocks.size());
uint16_t sgpr_limit = get_addr_sgpr_from_waves(program, program->num_waves);
std::map<unsigned, Assignment> assignments;
std::vector<Assignment> assignments(program->peekAllocationId());
for (Block& block : program->blocks) {
Location loc;
loc.block = &block;
@ -870,16 +871,16 @@ validate_ra(Program* program)
continue;
if (!op.isFixed())
err |= ra_fail(program, loc, Location(), "Operand %d is not assigned a register", i);
if (assignments.count(op.tempId()) && assignments[op.tempId()].reg != op.physReg())
if (assignments[op.tempId()].valid && assignments[op.tempId()].reg != op.physReg())
err |=
ra_fail(program, loc, assignments.at(op.tempId()).firstloc,
ra_fail(program, loc, assignments[op.tempId()].firstloc,
"Operand %d has an inconsistent register assignment with instruction", i);
if ((op.getTemp().type() == RegType::vgpr &&
op.physReg().reg_b + op.bytes() > (256 + program->config->num_vgprs) * 4) ||
(op.getTemp().type() == RegType::sgpr &&
op.physReg() + op.size() > program->config->num_sgprs &&
op.physReg() < sgpr_limit))
err |= ra_fail(program, loc, assignments.at(op.tempId()).firstloc,
err |= ra_fail(program, loc, assignments[op.tempId()].firstloc,
"Operand %d has an out-of-bounds register assignment", i);
if (op.physReg() == vcc && !program->needs_vcc)
err |= ra_fail(program, loc, Location(),
@ -889,8 +890,10 @@ validate_ra(Program* program)
err |= ra_fail(program, loc, Location(), "Operand %d not aligned correctly", i);
if (!assignments[op.tempId()].firstloc.block)
assignments[op.tempId()].firstloc = loc;
if (!assignments[op.tempId()].defloc.block)
if (!assignments[op.tempId()].defloc.block) {
assignments[op.tempId()].reg = op.physReg();
assignments[op.tempId()].valid = true;
}
}
for (unsigned i = 0; i < instr->definitions.size(); i++) {
@ -901,14 +904,14 @@ validate_ra(Program* program)
err |=
ra_fail(program, loc, Location(), "Definition %d is not assigned a register", i);
if (assignments[def.tempId()].defloc.block)
err |= ra_fail(program, loc, assignments.at(def.tempId()).defloc,
err |= ra_fail(program, loc, assignments[def.tempId()].defloc,
"Temporary %%%d also defined by instruction", def.tempId());
if ((def.getTemp().type() == RegType::vgpr &&
def.physReg().reg_b + def.bytes() > (256 + program->config->num_vgprs) * 4) ||
(def.getTemp().type() == RegType::sgpr &&
def.physReg() + def.size() > program->config->num_sgprs &&
def.physReg() < sgpr_limit))
err |= ra_fail(program, loc, assignments.at(def.tempId()).firstloc,
err |= ra_fail(program, loc, assignments[def.tempId()].firstloc,
"Definition %d has an out-of-bounds register assignment", i);
if (def.physReg() == vcc && !program->needs_vcc)
err |= ra_fail(program, loc, Location(),
@ -920,6 +923,7 @@ validate_ra(Program* program)
assignments[def.tempId()].firstloc = loc;
assignments[def.tempId()].defloc = loc;
assignments[def.tempId()].reg = def.physReg();
assignments[def.tempId()].valid = true;
}
}
}
@ -931,23 +935,22 @@ validate_ra(Program* program)
std::array<unsigned, 2048> regs; /* register file in bytes */
regs.fill(0);
std::set<Temp> live;
for (unsigned id : live_vars.live_out[block.index])
live.insert(Temp(id, program->temp_rc[id]));
IDSet live = live_vars.live_out[block.index];
/* remove killed p_phi sgpr operands */
for (Temp tmp : phi_sgpr_ops[block.index])
live.erase(tmp);
live.erase(tmp.id());
/* check live out */
for (Temp tmp : live) {
PhysReg reg = assignments.at(tmp.id()).reg;
for (unsigned id : live) {
Temp tmp(id, program->temp_rc[id]);
PhysReg reg = assignments[id].reg;
for (unsigned i = 0; i < tmp.bytes(); i++) {
if (regs[reg.reg_b + i]) {
err |= ra_fail(program, loc, Location(),
"Assignment of element %d of %%%d already taken by %%%d in live-out",
i, tmp.id(), regs[reg.reg_b + i]);
i, id, regs[reg.reg_b + i]);
}
regs[reg.reg_b + i] = tmp.id();
regs[reg.reg_b + i] = id;
}
}
regs.fill(0);
@ -958,7 +961,7 @@ validate_ra(Program* program)
/* check killed p_phi sgpr operands */
if (instr->opcode == aco_opcode::p_logical_end) {
for (Temp tmp : phi_sgpr_ops[block.index]) {
PhysReg reg = assignments.at(tmp.id()).reg;
PhysReg reg = assignments[tmp.id()].reg;
for (unsigned i = 0; i < tmp.bytes(); i++) {
if (regs[reg.reg_b + i])
err |= ra_fail(
@ -966,14 +969,14 @@ validate_ra(Program* program)
"Assignment of element %d of %%%d already taken by %%%d in live-out", i,
tmp.id(), regs[reg.reg_b + i]);
}
live.emplace(tmp);
live.insert(tmp.id());
}
}
for (const Definition& def : instr->definitions) {
if (!def.isTemp())
continue;
live.erase(def.getTemp());
live.erase(def.tempId());
}
/* don't count phi operands as live-in, since they are actually
@ -982,15 +985,16 @@ validate_ra(Program* program)
for (const Operand& op : instr->operands) {
if (!op.isTemp())
continue;
live.insert(op.getTemp());
live.insert(op.tempId());
}
}
}
for (Temp tmp : live) {
PhysReg reg = assignments.at(tmp.id()).reg;
for (unsigned id : live) {
Temp tmp(id, program->temp_rc[id]);
PhysReg reg = assignments[id].reg;
for (unsigned i = 0; i < tmp.bytes(); i++)
regs[reg.reg_b + i] = tmp.id();
regs[reg.reg_b + i] = id;
}
for (aco_ptr<Instruction>& instr : block.instructions) {
@ -999,7 +1003,7 @@ validate_ra(Program* program)
/* remove killed p_phi operands from regs */
if (instr->opcode == aco_opcode::p_logical_end) {
for (Temp tmp : phi_sgpr_ops[block.index]) {
PhysReg reg = assignments.at(tmp.id()).reg;
PhysReg reg = assignments[tmp.id()].reg;
for (unsigned i = 0; i < tmp.bytes(); i++)
regs[reg.reg_b + i] = 0;
}
@ -1021,11 +1025,11 @@ validate_ra(Program* program)
if (!def.isTemp())
continue;
Temp tmp = def.getTemp();
PhysReg reg = assignments.at(tmp.id()).reg;
PhysReg reg = assignments[tmp.id()].reg;
for (unsigned j = 0; j < tmp.bytes(); j++) {
if (regs[reg.reg_b + j])
err |= ra_fail(
program, loc, assignments.at(regs[reg.reg_b + j]).defloc,
program, loc, assignments[regs[reg.reg_b + j]].defloc,
"Assignment of element %d of %%%d already taken by %%%d from instruction", i,
tmp.id(), regs[reg.reg_b + j]);
regs[reg.reg_b + j] = tmp.id();
@ -1037,7 +1041,7 @@ validate_ra(Program* program)
for (unsigned j = reg.byte() & ~(written - 1); j < written; j++) {
unsigned written_reg = reg.reg() * 4u + j;
if (regs[written_reg] && regs[written_reg] != def.tempId())
err |= ra_fail(program, loc, assignments.at(regs[written_reg]).defloc,
err |= ra_fail(program, loc, assignments[regs[written_reg]].defloc,
"Assignment of element %d of %%%d overwrites the full register "
"taken by %%%d from instruction",
i, tmp.id(), regs[written_reg]);