intel/fs: Rework the loop of opt_combine_constants that collects constants

This is a bit more wordy, but it will greatly simplify some future
changes.

v2: Rebase on ADD3 changes.

Reviewed-by: Faith Ekstrand <faith.ekstrand@collabora.com>
Tested-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22274>
This commit is contained in:
Ian Romanick 2020-07-29 19:10:55 -07:00 committed by Marge Bot
parent 9e4bb4bfcf
commit 2016d9f46c

View file

@ -48,43 +48,22 @@ static const bool debug = false;
static bool
could_coissue(const struct intel_device_info *devinfo, const fs_inst *inst)
{
assert(inst->opcode == BRW_OPCODE_MOV ||
inst->opcode == BRW_OPCODE_CMP ||
inst->opcode == BRW_OPCODE_ADD ||
inst->opcode == BRW_OPCODE_MUL);
if (devinfo->ver != 7)
return false;
switch (inst->opcode) {
case BRW_OPCODE_MOV:
case BRW_OPCODE_CMP:
case BRW_OPCODE_ADD:
case BRW_OPCODE_MUL:
/* Only float instructions can coissue. We don't have a great
* understanding of whether or not something like float(int(a) + int(b))
* would be considered float (based on the destination type) or integer
* (based on the source types), so we take the conservative choice of
* only promoting when both destination and source are float.
*/
return inst->dst.type == BRW_REGISTER_TYPE_F &&
inst->src[0].type == BRW_REGISTER_TYPE_F;
default:
return false;
}
}
/**
* Returns true for instructions that don't support immediate sources.
*/
static bool
must_promote_imm(const struct intel_device_info *devinfo, const fs_inst *inst)
{
switch (inst->opcode) {
case SHADER_OPCODE_POW:
return devinfo->ver < 8;
case BRW_OPCODE_MAD:
case BRW_OPCODE_ADD3:
case BRW_OPCODE_LRP:
return true;
default:
return false;
}
/* Only float instructions can coissue. We don't have a great
* understanding of whether or not something like float(int(a) + int(b))
* would be considered float (based on the destination type) or integer
* (based on the source types), so we take the conservative choice of
* only promoting when both destination and source are float.
*/
return inst->dst.type == BRW_REGISTER_TYPE_F &&
inst->src[0].type == BRW_REGISTER_TYPE_F;
}
/** A box for putting fs_regs in a linked list. */
@ -423,6 +402,7 @@ can_promote_src_as_imm(const struct intel_device_info *devinfo, fs_inst *inst,
static void
add_candidate_immediate(struct table *table, fs_inst *inst, unsigned ip,
unsigned i,
bool must_promote,
const brw::idom_tree &idom, bblock_t *block,
const struct intel_device_info *devinfo,
void *const_ctx)
@ -442,8 +422,8 @@ add_candidate_immediate(struct table *table, fs_inst *inst, unsigned ip,
imm->inst = NULL;
imm->block = intersection;
imm->uses->push_tail(link(const_ctx, &inst->src[i]));
imm->uses_by_coissue += could_coissue(devinfo, inst);
imm->must_promote = imm->must_promote || must_promote_imm(devinfo, inst);
imm->uses_by_coissue += int(!must_promote);
imm->must_promote = imm->must_promote || must_promote;
imm->last_use_ip = ip;
if (type == BRW_REGISTER_TYPE_HF)
imm->is_half_float = true;
@ -456,8 +436,8 @@ add_candidate_immediate(struct table *table, fs_inst *inst, unsigned ip,
memcpy(imm->bytes, data, size);
imm->size = size;
imm->is_half_float = type == BRW_REGISTER_TYPE_HF;
imm->uses_by_coissue = could_coissue(devinfo, inst);
imm->must_promote = must_promote_imm(devinfo, inst);
imm->uses_by_coissue = int(!must_promote);
imm->must_promote = must_promote;
imm->first_use_ip = ip;
imm->last_use_ip = ip;
}
@ -483,18 +463,64 @@ fs_visitor::opt_combine_constants()
foreach_block_and_inst(block, fs_inst, inst, cfg) {
ip++;
if (!could_coissue(devinfo, inst) && !must_promote_imm(devinfo, inst))
continue;
switch (inst->opcode) {
case SHADER_OPCODE_POW:
assert(inst->src[0].file != IMM);
for (int i = 0; i < inst->sources; i++) {
if (inst->src[i].file != IMM)
continue;
if (inst->src[1].file == IMM && devinfo->ver < 8) {
add_candidate_immediate(&table, inst, ip, 1, true, idom, block,
devinfo, const_ctx);
}
if (can_promote_src_as_imm(devinfo, inst, i))
continue;
break;
add_candidate_immediate(&table, inst, ip, i, idom, block, devinfo,
const_ctx);
case BRW_OPCODE_ADD3:
case BRW_OPCODE_MAD: {
for (int i = 0; i < inst->sources; i++) {
if (inst->src[i].file != IMM)
continue;
if (can_promote_src_as_imm(devinfo, inst, i))
continue;
add_candidate_immediate(&table, inst, ip, i, true, idom, block,
devinfo, const_ctx);
}
break;
}
case BRW_OPCODE_LRP:
for (int i = 0; i < inst->sources; i++) {
if (inst->src[i].file != IMM)
continue;
add_candidate_immediate(&table, inst, ip, i, true, idom, block,
devinfo, const_ctx);
}
break;
case BRW_OPCODE_MOV:
if (could_coissue(devinfo, inst) && inst->src[0].file == IMM) {
add_candidate_immediate(&table, inst, ip, 0, false, idom, block,
devinfo, const_ctx);
}
break;
case BRW_OPCODE_CMP:
case BRW_OPCODE_ADD:
case BRW_OPCODE_MUL:
assert(inst->src[0].file != IMM);
if (could_coissue(devinfo, inst) && inst->src[1].file == IMM) {
add_candidate_immediate(&table, inst, ip, 1, false, idom, block,
devinfo, const_ctx);
}
break;
default:
break;
}
}