From 12a022cf45fcd502606a478d3fd09578f9e61f40 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 23 Apr 2025 10:21:45 -0700 Subject: [PATCH] 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 Part-of: --- src/intel/compiler/brw_opt_algebraic.cpp | 86 ++++++++---------------- 1 file changed, 29 insertions(+), 57 deletions(-) diff --git a/src/intel/compiler/brw_opt_algebraic.cpp b/src/intel/compiler/brw_opt_algebraic.cpp index db6f2a40248..31cf63cd984 100644 --- a/src/intel/compiler/brw_opt_algebraic.cpp +++ b/src/intel/compiler/brw_opt_algebraic.cpp @@ -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