From 11602d2d36d319c2f185979effa4ed3c3342678f Mon Sep 17 00:00:00 2001 From: Rhys Perry Date: Wed, 27 Oct 2021 09:34:44 +0100 Subject: [PATCH] aco: use std::vector and IDSet in RA validator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rhys Perry Reviewed-by: Daniel Schürmann Part-of: --- src/amd/compiler/aco_validate.cpp | 56 +++++++++++++++++-------------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/src/amd/compiler/aco_validate.cpp b/src/amd/compiler/aco_validate.cpp index 0badb3ce17a..8c5a84ac3f9 100644 --- a/src/amd/compiler/aco_validate.cpp +++ b/src/amd/compiler/aco_validate.cpp @@ -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> phi_sgpr_ops(program->blocks.size()); uint16_t sgpr_limit = get_addr_sgpr_from_waves(program, program->num_waves); - std::map assignments; + std::vector assignments(program->peekAllocationId()); for (Block& block : program->blocks) { Location loc; loc.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 regs; /* register file in bytes */ regs.fill(0); - std::set 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& 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]);