brw/algebraic: Greatly simplify brw_opt_constant_fold_instruction
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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user