brw/algebraic: Greatly simplify brw_opt_constant_fold_instruction
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

brw_opt_constant_fold_instruction can either do nothing or replace the
instruction with a MOV of an immediate value. Previously each opcode
case would perform this replacement, and code at the bottom of the
function would verify the results.

It is much simpler if each opcode case calculates a result in a brw_reg,
and code at the bottom of the function performs the replacement. There
are two outlier cases that cannot use this pattern: MAD and
BROADCAST. These cases simply return directly from the switch-statement
after performing the replacement.

Reviewed-by: Matt Turner <mattst88@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34707>
This commit is contained in:
Ian Romanick 2025-04-23 10:21:45 -07:00 committed by Marge Bot
parent 9a946f8125
commit 12a022cf45

View file

@ -135,7 +135,9 @@ fold_multiplicands_of_MAD(brw_inst *inst)
bool
brw_opt_constant_fold_instruction(const intel_device_info *devinfo, brw_inst *inst)
{
bool progress = false;
brw_reg result;
result.file = BAD_FILE;
switch (inst->opcode) {
case BRW_OPCODE_ADD:
@ -146,15 +148,12 @@ brw_opt_constant_fold_instruction(const intel_device_info *devinfo, brw_inst *in
const uint64_t src0 = src_as_uint(inst->src[0]);
const uint64_t src1 = src_as_uint(inst->src[1]);
inst->src[0] = brw_imm_for_type(src0 + src1, inst->dst.type);
result = brw_imm_for_type(src0 + src1, inst->dst.type);
} else {
assert(inst->src[0].type == BRW_TYPE_F);
inst->src[0].f += inst->src[1].f;
result = brw_imm_f(inst->src[0].f + inst->src[1].f);
}
inst->opcode = BRW_OPCODE_MOV;
inst->resize_sources(1);
progress = true;
break;
case BRW_OPCODE_ADD3:
@ -165,11 +164,7 @@ brw_opt_constant_fold_instruction(const intel_device_info *devinfo, brw_inst *in
const uint64_t src1 = src_as_uint(inst->src[1]);
const uint64_t src2 = src_as_uint(inst->src[2]);
inst->opcode = BRW_OPCODE_MOV;
inst->src[0] = brw_imm_for_type(src0 + src1 + src2,
inst->dst.type);
inst->resize_sources(1);
progress = true;
result = brw_imm_for_type(src0 + src1 + src2, inst->dst.type);
}
break;
@ -179,10 +174,7 @@ brw_opt_constant_fold_instruction(const intel_device_info *devinfo, brw_inst *in
const uint64_t src0 = src_as_uint(inst->src[0]);
const uint64_t src1 = src_as_uint(inst->src[1]);
inst->opcode = BRW_OPCODE_MOV;
inst->src[0] = brw_imm_for_type(src0 & src1, inst->dst.type);
inst->resize_sources(1);
progress = true;
result = brw_imm_for_type(src0 & src1, inst->dst.type);
break;
}
@ -201,8 +193,7 @@ brw_opt_constant_fold_instruction(const intel_device_info *devinfo, brw_inst *in
ASSERTED bool folded = brw_opt_constant_fold_instruction(devinfo, inst);
assert(folded);
progress = true;
break;
return true;
}
break;
@ -235,10 +226,7 @@ brw_opt_constant_fold_instruction(const intel_device_info *devinfo, brw_inst *in
break;
if (inst->src[0].is_zero() || inst->src[1].is_zero()) {
inst->opcode = BRW_OPCODE_MOV;
inst->src[0] = brw_imm_d(0);
inst->resize_sources(1);
progress = true;
result = brw_imm_d(0);
break;
}
@ -246,10 +234,7 @@ brw_opt_constant_fold_instruction(const intel_device_info *devinfo, brw_inst *in
const uint64_t src0 = src_as_uint(inst->src[0]);
const uint64_t src1 = src_as_uint(inst->src[1]);
inst->opcode = BRW_OPCODE_MOV;
inst->src[0] = brw_imm_for_type(src0 * src1, inst->dst.type);
inst->resize_sources(1);
progress = true;
result = brw_imm_for_type(src0 * src1, inst->dst.type);
break;
}
break;
@ -259,10 +244,7 @@ brw_opt_constant_fold_instruction(const intel_device_info *devinfo, brw_inst *in
const uint64_t src0 = src_as_uint(inst->src[0]);
const uint64_t src1 = src_as_uint(inst->src[1]);
inst->opcode = BRW_OPCODE_MOV;
inst->src[0] = brw_imm_for_type(src0 | src1, inst->dst.type);
inst->resize_sources(1);
progress = true;
result = brw_imm_for_type(src0 | src1, inst->dst.type);
break;
}
@ -275,8 +257,6 @@ brw_opt_constant_fold_instruction(const intel_device_info *devinfo, brw_inst *in
*/
assert(!inst->saturate);
brw_reg result;
switch (brw_type_size_bytes(inst->src[0].type)) {
case 2:
result = brw_imm_uw(0x0ffff & (inst->src[0].ud << (inst->src[1].ud & 0x1f)));
@ -292,11 +272,7 @@ brw_opt_constant_fold_instruction(const intel_device_info *devinfo, brw_inst *in
unreachable("Invalid source size.");
}
inst->opcode = BRW_OPCODE_MOV;
inst->src[0] = retype(result, inst->dst.type);
inst->resize_sources(1);
progress = true;
result = retype(result, inst->dst.type);
}
break;
@ -312,44 +288,40 @@ brw_opt_constant_fold_instruction(const intel_device_info *devinfo, brw_inst *in
*/
inst->exec_size = 8 * reg_unit(devinfo);
assert(inst->size_written == inst->dst.component_size(inst->exec_size));
progress = true;
return true;
}
break;
case SHADER_OPCODE_SHUFFLE:
if (inst->src[0].file == IMM) {
inst->opcode = BRW_OPCODE_MOV;
inst->resize_sources(1);
progress = true;
}
if (inst->src[0].file == IMM)
result = inst->src[0];
break;
case FS_OPCODE_DDX_COARSE:
case FS_OPCODE_DDX_FINE:
case FS_OPCODE_DDY_COARSE:
case FS_OPCODE_DDY_FINE:
if (is_uniform(inst->src[0]) || inst->src[0].is_scalar) {
inst->opcode = BRW_OPCODE_MOV;
inst->src[0] = retype(brw_imm_uq(0), inst->dst.type);
progress = true;
}
if (is_uniform(inst->src[0]) || inst->src[0].is_scalar)
result = retype(brw_imm_uq(0), inst->dst.type);
break;
default:
break;
}
#ifndef NDEBUG
/* The function is only intended to do constant folding, so the result of
* progress must be a MOV of an immediate value.
*/
if (progress) {
assert(inst->opcode == BRW_OPCODE_MOV);
assert(inst->src[0].file == IMM);
}
#endif
if (result.file != BAD_FILE) {
assert(result.file == IMM);
return progress;
inst->opcode = BRW_OPCODE_MOV;
inst->src[0] = result;
inst->resize_sources(1);
return true;
}
return false;
}
bool