aco: add check_vop3_operands()

This will be useful when taking advantage of GFX10 features.

No pipeline-db changes.

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/2883>
This commit is contained in:
Rhys Perry
2019-11-22 14:50:41 +00:00
committed by Marge Bot
parent cef7879719
commit fcf52eb42d
+34 -24
View File
@@ -505,6 +505,33 @@ bool valu_can_accept_vgpr(aco_ptr<Instruction>& instr, unsigned operand)
return true;
}
/* check constant bus and literal limitations */
bool check_vop3_operands(opt_ctx& ctx, unsigned num_operands, Operand *operands)
{
int limit = 1;
unsigned num_sgprs = 0;
unsigned sgpr[] = {0, 0};
for (unsigned i = 0; i < num_operands; i++) {
Operand op = operands[i];
if (op.hasRegClass() && op.regClass().type() == RegType::sgpr) {
/* two reads of the same SGPR count as 1 to the limit */
if (op.tempId() != sgpr[0] && op.tempId() != sgpr[1]) {
if (num_sgprs < 2)
sgpr[num_sgprs++] = op.tempId();
limit--;
if (limit < 0)
return false;
}
} else if (op.isLiteral()) {
return false;
}
}
return true;
}
bool parse_base_offset(opt_ctx &ctx, Instruction* instr, unsigned op_index, Temp *base, uint32_t *offset)
{
Operand op = instr->operands[op_index];
@@ -1524,17 +1551,8 @@ bool match_op3_for_vop3(opt_ctx &ctx, aco_opcode op1, aco_opcode op2,
}
/* check operands */
unsigned sgpr_id = 0;
for (unsigned i = 0; i < 3; i++) {
Operand op = operands[i];
if (op.isLiteral()) {
return false;
} else if (op.isTemp() && op.getTemp().type() == RegType::sgpr) {
if (sgpr_id && sgpr_id != op.tempId())
return false;
sgpr_id = op.tempId();
}
}
if (!check_vop3_operands(ctx, 3, operands))
return false;
return true;
}
@@ -2144,25 +2162,17 @@ void combine_instruction(opt_ctx &ctx, Block& block, aco_ptr<Instruction>& instr
unsigned omod = 0;
bool clamp = false;
bool need_vop3 = false;
int num_sgpr = 0;
unsigned cur_sgpr = 0;
op[0] = mul_instr->operands[0];
op[1] = mul_instr->operands[1];
op[2] = instr->operands[add_op_idx];
for (unsigned i = 0; i < 3; i++)
{
if (op[i].isLiteral())
return;
if (op[i].isTemp() && op[i].getTemp().type() == RegType::sgpr && op[i].tempId() != cur_sgpr) {
num_sgpr++;
cur_sgpr = op[i].tempId();
}
// TODO: would be better to check this before selecting a mul instr?
if (!check_vop3_operands(ctx, 3, op))
return;
for (unsigned i = 0; i < 3; i++) {
if (!(i == 0 || (op[i].isTemp() && op[i].getTemp().type() == RegType::vgpr)))
need_vop3 = true;
}
// TODO: would be better to check this before selecting a mul instr?
if (num_sgpr > 1)
return;
if (mul_instr->isVOP3()) {
VOP3A_instruction* vop3 = static_cast<VOP3A_instruction*> (mul_instr);