aco/ra: use DefInfo for get_reg_specified

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/30761>
This commit is contained in:
Rhys Perry
2024-08-27 17:09:00 +01:00
committed by Marge Bot
parent 1e6741bf6b
commit 16ff51bb37

View File

@@ -208,12 +208,16 @@ struct DefInfo {
PhysRegInterval bounds;
uint8_t size;
uint8_t stride;
/* Even if stride=4, we might be able to write to the high half instead without preserving the
* low half. In that case, data_stride=2. */
uint8_t data_stride;
RegClass rc;
DefInfo(ra_ctx& ctx, aco_ptr<Instruction>& instr, RegClass rc_, int operand) : rc(rc_)
{
size = rc.size();
stride = get_stride(rc);
data_stride = 0;
bounds = get_reg_bounds(ctx, rc);
@@ -226,9 +230,8 @@ struct DefInfo {
if (info.second > rc.bytes()) {
rc = RegClass::get(rc.type(), info.second);
size = rc.size();
/* we might still be able to put the definition in the high half,
* but that's only useful for affinities and this information isn't
* used for them */
if (info.second > stride)
data_stride = stride;
stride = align(stride, info.second);
if (!rc.is_subdword())
stride = DIV_ROUND_UP(stride, 4);
@@ -249,6 +252,9 @@ struct DefInfo {
if (imageGather4D16Bug)
bounds.size -= MAX2(rc.bytes() / 4 - ctx.num_linear_vgprs, 0);
}
if (!data_stride)
data_stride = rc.is_subdword() ? stride : (stride * 4);
}
};
@@ -670,7 +676,6 @@ get_subdword_definition_info(Program* program, const aco_ptr<Instruction>& instr
return std::make_pair(4u, 6u);
break;
}
default: break;
}
@@ -1379,45 +1384,33 @@ get_reg_impl(ra_ctx& ctx, const RegisterFile& reg_file,
bool
get_reg_specified(ra_ctx& ctx, const RegisterFile& reg_file, RegClass rc,
aco_ptr<Instruction>& instr, PhysReg reg)
aco_ptr<Instruction>& instr, PhysReg reg, int operand)
{
/* catch out-of-range registers */
if (reg >= PhysReg{512})
return false;
std::pair<unsigned, unsigned> sdw_def_info;
if (rc.is_subdword())
sdw_def_info = get_subdword_definition_info(ctx.program, instr, rc);
DefInfo info(ctx, instr, rc, operand);
if (rc.is_subdword() && reg.byte() % sdw_def_info.first)
return false;
if (!rc.is_subdword() && reg.byte())
if (reg.reg_b % info.data_stride)
return false;
if (rc.type() == RegType::sgpr && reg % get_stride(rc) != 0)
return false;
assert(util_is_power_of_two_nonzero(info.stride));
reg.reg_b &= ~(info.stride - 1);
PhysRegInterval reg_win = {reg, rc.size()};
PhysRegInterval bounds = get_reg_bounds(ctx, rc);
PhysRegInterval reg_win = {PhysReg(reg.reg()), info.rc.size()};
PhysRegInterval vcc_win = {vcc, 2};
/* VCC is outside the bounds */
bool is_vcc = rc.type() == RegType::sgpr && vcc_win.contains(reg_win) && ctx.program->needs_vcc;
bool is_m0 = rc == s1 && reg == m0 && can_write_m0(instr);
if (!bounds.contains(reg_win) && !is_vcc && !is_m0)
bool is_vcc =
info.rc.type() == RegType::sgpr && vcc_win.contains(reg_win) && ctx.program->needs_vcc;
bool is_m0 = info.rc == s1 && reg == m0 && can_write_m0(instr);
if (!info.bounds.contains(reg_win) && !is_vcc && !is_m0)
return false;
if (rc.is_subdword()) {
PhysReg test_reg = reg;
if (sdw_def_info.second > rc.bytes())
test_reg.reg_b &= ~(align(sdw_def_info.first, sdw_def_info.second) - 1);
if (reg_file.test(test_reg, sdw_def_info.second))
return false;
} else {
if (reg_file.test(reg, rc.bytes()))
return false;
}
if (reg_file.test(reg, info.rc.bytes()))
return false;
adjust_max_used_regs(ctx, rc, reg_win.lo());
adjust_max_used_regs(ctx, info.rc, reg_win.lo());
return true;
}
@@ -1562,7 +1555,8 @@ is_mimg_vaddr_intact(ra_ctx& ctx, const RegisterFile& reg_file, Instruction* ins
}
std::optional<PhysReg>
get_reg_vector(ra_ctx& ctx, const RegisterFile& reg_file, Temp temp, aco_ptr<Instruction>& instr)
get_reg_vector(ra_ctx& ctx, const RegisterFile& reg_file, Temp temp, aco_ptr<Instruction>& instr,
int operand)
{
Instruction* vec = ctx.vectors[temp.id()];
unsigned first_operand = vec->format == Format::MIMG ? 3 : 0;
@@ -1587,7 +1581,7 @@ get_reg_vector(ra_ctx& ctx, const RegisterFile& reg_file, Temp temp, aco_ptr<Ins
ctx.assignments[op.tempId()].assigned) {
PhysReg reg = ctx.assignments[op.tempId()].reg;
reg.reg_b += (our_offset - their_offset);
if (get_reg_specified(ctx, reg_file, temp.regClass(), instr, reg))
if (get_reg_specified(ctx, reg_file, temp.regClass(), instr, reg, operand))
return reg;
/* return if MIMG vaddr components don't remain vector-aligned */
@@ -1606,7 +1600,7 @@ get_reg_vector(ra_ctx& ctx, const RegisterFile& reg_file, Temp temp, aco_ptr<Ins
if (reg) {
reg->reg_b += our_offset;
/* make sure to only use byte offset if the instruction supports it */
if (get_reg_specified(ctx, reg_file, temp.regClass(), instr, *reg))
if (get_reg_specified(ctx, reg_file, temp.regClass(), instr, *reg, operand))
return reg;
}
}
@@ -1740,7 +1734,7 @@ get_reg(ra_ctx& ctx, const RegisterFile& reg_file, Temp temp,
if (affinity.assigned) {
PhysReg reg = affinity.reg;
reg.reg_b -= offset;
if (get_reg_specified(ctx, reg_file, temp.regClass(), instr, reg))
if (get_reg_specified(ctx, reg_file, temp.regClass(), instr, reg, operand_index))
return reg;
}
}
@@ -1751,23 +1745,23 @@ get_reg(ra_ctx& ctx, const RegisterFile& reg_file, Temp temp,
if (ctx.assignments[temp.id()].affinity) {
assignment& affinity = ctx.assignments[ctx.assignments[temp.id()].affinity];
if (affinity.assigned) {
if (get_reg_specified(ctx, reg_file, temp.regClass(), instr, affinity.reg))
if (get_reg_specified(ctx, reg_file, temp.regClass(), instr, affinity.reg, operand_index))
return affinity.reg;
}
}
if (ctx.assignments[temp.id()].vcc) {
if (get_reg_specified(ctx, reg_file, temp.regClass(), instr, vcc))
if (get_reg_specified(ctx, reg_file, temp.regClass(), instr, vcc, operand_index))
return vcc;
}
if (ctx.assignments[temp.id()].m0) {
if (get_reg_specified(ctx, reg_file, temp.regClass(), instr, m0))
if (get_reg_specified(ctx, reg_file, temp.regClass(), instr, m0, operand_index))
return m0;
}
std::optional<PhysReg> res;
if (ctx.vectors.find(temp.id()) != ctx.vectors.end()) {
res = get_reg_vector(ctx, reg_file, temp, instr);
res = get_reg_vector(ctx, reg_file, temp, instr, operand_index);
if (res)
return *res;
}
@@ -1776,7 +1770,8 @@ get_reg(ra_ctx& ctx, const RegisterFile& reg_file, Temp temp,
for (const Operand& op : instr->operands) {
if (op.isTemp() && op.isFirstKillBeforeDef() && op.regClass() == temp.regClass()) {
assert(op.isFixed());
if (get_reg_specified(ctx, reg_file, temp.regClass(), instr, op.physReg()))
if (get_reg_specified(ctx, reg_file, temp.regClass(), instr, op.physReg(),
operand_index))
return op.physReg();
}
}
@@ -2242,7 +2237,7 @@ get_regs_for_phis(ra_ctx& ctx, Block& block, RegisterFile& register_file,
if (!all_same)
continue;
if (!get_reg_specified(ctx, register_file, definition.regClass(), phi, reg))
if (!get_reg_specified(ctx, register_file, definition.regClass(), phi, reg, -1))
continue;
definition.setFixed(reg);
@@ -2261,7 +2256,7 @@ get_regs_for_phis(ra_ctx& ctx, Block& block, RegisterFile& register_file,
ctx.assignments[ctx.assignments[definition.tempId()].affinity].assigned) {
assignment& affinity = ctx.assignments[ctx.assignments[definition.tempId()].affinity];
assert(affinity.rc == definition.regClass());
if (get_reg_specified(ctx, register_file, definition.regClass(), phi, affinity.reg)) {
if (get_reg_specified(ctx, register_file, definition.regClass(), phi, affinity.reg, -1)) {
definition.setFixed(affinity.reg);
register_file.fill(definition);
ctx.assignments[definition.tempId()].set(definition);
@@ -2276,7 +2271,7 @@ get_regs_for_phis(ra_ctx& ctx, Block& block, RegisterFile& register_file,
continue;
PhysReg reg = op.physReg();
if (get_reg_specified(ctx, register_file, definition.regClass(), phi, reg)) {
if (get_reg_specified(ctx, register_file, definition.regClass(), phi, reg, -1)) {
definition.setFixed(reg);
register_file.fill(definition);
ctx.assignments[definition.tempId()].set(definition);
@@ -3147,18 +3142,18 @@ register_allocation(Program* program, ra_test_policy policy)
RegClass rc = definition->regClass();
for (unsigned j = 0; j < i; j++)
reg.reg_b += instr->definitions[j].bytes();
if (get_reg_specified(ctx, register_file, rc, instr, reg)) {
if (get_reg_specified(ctx, register_file, rc, instr, reg, -1)) {
definition->setFixed(reg);
} else if (i == 0) {
RegClass vec_rc = RegClass::get(rc.type(), instr->operands[0].bytes());
DefInfo info(ctx, ctx.pseudo_dummy, vec_rc, -1);
std::optional<PhysReg> res = get_reg_simple(ctx, register_file, info);
if (res && get_reg_specified(ctx, register_file, rc, instr, *res))
if (res && get_reg_specified(ctx, register_file, rc, instr, *res, -1))
definition->setFixed(*res);
} else if (instr->definitions[i - 1].isFixed()) {
reg = instr->definitions[i - 1].physReg();
reg.reg_b += instr->definitions[i - 1].bytes();
if (get_reg_specified(ctx, register_file, rc, instr, reg))
if (get_reg_specified(ctx, register_file, rc, instr, reg, -1))
definition->setFixed(reg);
}
} else if (instr->opcode == aco_opcode::p_parallelcopy) {
@@ -3170,7 +3165,7 @@ register_allocation(Program* program, ra_test_policy policy)
} else if (instr->opcode == aco_opcode::p_extract_vector) {
PhysReg reg = instr->operands[0].physReg();
reg.reg_b += definition->bytes() * instr->operands[1].constantValue();
if (get_reg_specified(ctx, register_file, definition->regClass(), instr, reg))
if (get_reg_specified(ctx, register_file, definition->regClass(), instr, reg, -1))
definition->setFixed(reg);
} else if (instr->opcode == aco_opcode::p_create_vector) {
PhysReg reg = get_reg_create_vector(ctx, register_file, definition->getTemp(),