aco/optimizer: use new helpers to optimize mul(b2f(a), b)

Foz-DB Navi48:
Totals from 979 (1.19% of 82419) affected shaders:
Instrs: 3630560 -> 3629463 (-0.03%); split: -0.03%, +0.00%
CodeSize: 19154176 -> 19147124 (-0.04%); split: -0.04%, +0.00%
Latency: 17700546 -> 17699505 (-0.01%); split: -0.01%, +0.01%
InvThroughput: 3143808 -> 3143254 (-0.02%); split: -0.02%, +0.01%
SClause: 76410 -> 76405 (-0.01%); split: -0.01%, +0.00%
Copies: 256544 -> 256554 (+0.00%); split: -0.02%, +0.02%
PreVGPRs: 40868 -> 40835 (-0.08%)
VALU: 2003291 -> 2002466 (-0.04%); split: -0.04%, +0.00%
SALU: 514000 -> 514006 (+0.00%)
VOPD: 3254 -> 3256 (+0.06%); split: +0.12%, -0.06%

Foz-DB Navi21:
Totals from 926 (1.12% of 82387) affected shaders:
MaxWaves: 21538 -> 21542 (+0.02%)
Instrs: 2984216 -> 2983187 (-0.03%); split: -0.04%, +0.00%
CodeSize: 16104112 -> 16097272 (-0.04%); split: -0.05%, +0.00%
VGPRs: 46864 -> 46848 (-0.03%)
Latency: 15678064 -> 15677099 (-0.01%); split: -0.01%, +0.00%
InvThroughput: 3779550 -> 3778230 (-0.03%); split: -0.04%, +0.01%
VClause: 81590 -> 81598 (+0.01%)
SClause: 70753 -> 70751 (-0.00%); split: -0.01%, +0.00%
Copies: 240446 -> 240466 (+0.01%); split: -0.01%, +0.02%
PreSGPRs: 51121 -> 51062 (-0.12%)
PreVGPRs: 38538 -> 38505 (-0.09%)
VALU: 1978847 -> 1977777 (-0.05%); split: -0.06%, +0.00%
SALU: 439184 -> 439212 (+0.01%)

Reviewed-by: Daniel Schürmann <daniel@schuermann.dev>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38150>
This commit is contained in:
Georg Lehmann
2024-12-14 16:51:55 +01:00
committed by Marge Bot
parent f0e24284f5
commit e8f5b9374b
2 changed files with 57 additions and 40 deletions
+43 -40
View File
@@ -72,7 +72,6 @@ enum Label {
label_clamp = 1ull << 36,
label_insert = 1ull << 38,
label_f2f16 = 1ull << 39,
label_b2f = 1ull << 40,
label_b2i = 1ull << 41,
};
@@ -83,8 +82,8 @@ static constexpr uint64_t input_mod_labels =
label_abs_fp16 | label_abs_fp32_64 | label_neg_fp16 | label_neg_fp32_64;
static constexpr uint64_t temp_labels = label_temp | label_uniform_bool | label_scc_invert |
label_b2f | label_b2i | input_mod_labels |
label_fcanonicalize_fp32_64 | label_fcanonicalize_fp16;
label_b2i | input_mod_labels | label_fcanonicalize_fp32_64 |
label_fcanonicalize_fp16;
static constexpr uint64_t val_labels = label_constant | label_combined_instr;
@@ -249,14 +248,6 @@ struct ssa_info {
bool is_f2f16() { return label & label_f2f16; }
void set_b2f(Temp b2f_val)
{
add_label(label_b2f);
temp = b2f_val;
}
bool is_b2f() { return label & label_b2f; }
void set_uniform_bitwise() { add_label(label_uniform_bitwise); }
bool is_uniform_bitwise() { return label & label_uniform_bitwise; }
@@ -2902,9 +2893,7 @@ label_instruction(opt_ctx& ctx, aco_ptr<Instruction>& instr)
break;
}
case aco_opcode::v_cndmask_b32:
if (instr->operands[0].constantEquals(0) && instr->operands[1].constantEquals(0x3f800000u))
ctx.info[instr->definitions[0].tempId()].set_b2f(instr->operands[2].getTemp());
else if (instr->operands[0].constantEquals(0) && instr->operands[1].constantEquals(1))
if (instr->operands[0].constantEquals(0) && instr->operands[1].constantEquals(1))
ctx.info[instr->definitions[0].tempId()].set_b2i(instr->operands[2].getTemp());
break;
@@ -4637,6 +4626,39 @@ create_med3_cb(opt_ctx& ctx, alu_opt_info& info)
return false;
}
bool
check_constant(opt_ctx& ctx, alu_opt_info& info, unsigned idx, uint32_t expected)
{
assert(idx < info.operands.size());
aco_type type = {aco_base_type_uint, 1, 32}; /* maybe param in the future, if needed. */
uint64_t constant;
return op_info_get_constant(ctx, info.operands[idx], type, &constant) && constant == expected;
}
template <unsigned idx, uint32_t expected>
bool
check_const_cb(opt_ctx& ctx, alu_opt_info& info)
{
return check_constant(ctx, info, idx, expected);
}
template <uint32_t expected>
bool
remove_const_cb(opt_ctx& ctx, alu_opt_info& info)
{
if (!check_constant(ctx, info, info.operands.size() - 1, expected))
return false;
info.operands.pop_back();
return true;
}
template <combine_instr_callback func1, combine_instr_callback func2>
bool
and_cb(opt_ctx& ctx, alu_opt_info& info)
{
return func1(ctx, info) && func2(ctx, info);
}
bool
is_mul(Instruction* instr)
{
@@ -4749,32 +4771,6 @@ combine_instruction(opt_ctx& ctx, aco_ptr<Instruction>& instr)
}
if (instr->isSDWA()) {
/* v_mul_f32(v_cndmask_b32(0, 1.0, cond), a) -> v_cndmask_b32(0, a, cond) */
} else if (((instr->opcode == aco_opcode::v_mul_f32 && !instr->definitions[0].isNaNPreserve() &&
!instr->definitions[0].isInfPreserve()) ||
(instr->opcode == aco_opcode::v_mul_legacy_f32 &&
!instr->definitions[0].isSZPreserve())) &&
!instr->usesModifiers() && !ctx.fp_mode.must_flush_denorms32) {
for (unsigned i = 0; i < 2; i++) {
if (instr->operands[i].isTemp() && ctx.info[instr->operands[i].tempId()].is_b2f() &&
ctx.uses[instr->operands[i].tempId()] == 1 && instr->operands[!i].isTemp() &&
instr->operands[!i].getTemp().type() == RegType::vgpr) {
ctx.uses[instr->operands[i].tempId()]--;
ctx.uses[ctx.info[instr->operands[i].tempId()].temp.id()]++;
aco_ptr<Instruction> new_instr{
create_instruction(aco_opcode::v_cndmask_b32, Format::VOP2, 3, 1)};
new_instr->operands[0] = Operand::zero();
new_instr->operands[1] = instr->operands[!i];
new_instr->operands[2] = Operand(ctx.info[instr->operands[i].tempId()].temp);
new_instr->definitions[0] = instr->definitions[0];
new_instr->pass_flags = instr->pass_flags;
instr = std::move(new_instr);
ctx.info[instr->definitions[0].tempId()].label = 0;
ctx.info[instr->definitions[0].tempId()].parent_instr = instr.get();
return;
}
}
} else if (instr->opcode == aco_opcode::v_or_b32 && ctx.program->gfx_level >= GFX9) {
if (combine_three_valu_op(ctx, instr, aco_opcode::s_or_b32, aco_opcode::v_or3_b32, "012",
1 | 2)) {
@@ -5005,6 +5001,13 @@ combine_instruction(opt_ctx& ctx, aco_ptr<Instruction>& instr)
} else if (info.opcode == aco_opcode::v_min_i16_e64) {
add_opt(v_min_i16_e64, v_min3_i16, 0x3, "120", nullptr, true);
add_opt(v_max_i16_e64, v_med3_i16, 0x3, "012", create_med3_cb<true>, true);
} else if (((info.opcode == aco_opcode::v_mul_f32 && !info.defs[0].isNaNPreserve() &&
!info.defs[0].isInfPreserve()) ||
(info.opcode == aco_opcode::v_mul_legacy_f32 && !info.defs[0].isSZPreserve())) &&
!info.clamp && !info.omod && !ctx.fp_mode.must_flush_denorms32) {
/* v_mul_f32(a, v_cndmask_b32(0, 1.0, cond)) -> v_cndmask_b32(0, a, cond) */
add_opt(v_cndmask_b32, v_cndmask_b32, 0x3, "1032",
and_cb<check_const_cb<0, 0>, remove_const_cb<0x3f800000>>, true);
}
if (match_and_apply_patterns(ctx, info, patterns)) {
+14
View File
@@ -2185,3 +2185,17 @@ BEGIN_TEST(optimizer.fp64_clamp)
finish_opt_test();
END_TEST
BEGIN_TEST(optimizer.mul_b2f)
//>> v1: %a:v[0], s2: %b:s[0-1] = p_startpgm
if (!setup_cs("v1 s2", GFX11))
return;
//>> v1: %res0 = v_cndmask_b32 0, %a, %b
//! p_unit_test 0, %res0
Temp cond = bld.vop2_e64(aco_opcode::v_cndmask_b32, bld.def(v1), Operand::c32(0),
Operand::c32(0x3F800000), inputs[1]);
writeout(0, bld.vop2(aco_opcode::v_mul_f32, bld.def(v1), inputs[0], cond));
finish_opt_test();
END_TEST