intel/brw: Eliminate dead flag writes

This prevents a couple small regressions in the next commit.

The only changes in shader-db or fossil-db were on Skylake. This seems
to eliminate an unused flags write that doesn't exist on other platforms.
With that flag write eliminated, a later CMP can be scheduled better.

I did not investigate this further.

v2: Clean up some unnecessary bits and add some comments to
can_elminate_conditional_mod. Suggested by Ken and Matt.

Skylake
Totals:
Cycle count: 14665454524 -> 14665454444 (-0.00%)

Totals from 10 (0.00% of 625685) affected shaders:
Cycle count: 38630 -> 38550 (-0.21%)

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29774>
This commit is contained in:
Ian Romanick 2024-06-26 12:08:12 -07:00
parent 169f8ec227
commit 6da4649191

View file

@ -72,6 +72,32 @@ can_omit_write(const fs_inst *inst)
}
}
static bool
can_eliminate_conditional_mod(const intel_device_info *devinfo,
const fs_inst *inst, BITSET_WORD *flag_live)
{
/* CMP, CMPN, and CSEL must have a conditional modifier because the
* modifier determines what the instruction does. SEL with a conditional
* modifier has a special meaning (i.e., makes the instruction behave as
* MIN or MAX), so those cannot be eliminated either.
*/
if (inst->conditional_mod == BRW_CONDITIONAL_NONE ||
inst->opcode == BRW_OPCODE_CMP ||
inst->opcode == BRW_OPCODE_CMPN ||
inst->opcode == BRW_OPCODE_SEL ||
inst->opcode == BRW_OPCODE_CSEL) {
return false;
}
/* The conditional modifier can be eliminated if none of the flags written
* are read.
*/
const BITSET_WORD flags_written = inst->flags_written(devinfo);
assert(flags_written != 0);
return (flag_live[0] & flags_written) == 0;
}
bool
brw_fs_opt_dead_code_eliminate(fs_visitor &s)
{
@ -106,6 +132,9 @@ brw_fs_opt_dead_code_eliminate(fs_visitor &s)
}
}
if (can_eliminate_conditional_mod(devinfo, inst, flag_live))
inst->conditional_mod = BRW_CONDITIONAL_NONE;
if (inst->dst.is_null() && can_eliminate(devinfo, inst, flag_live) &&
!(inst->opcode == BRW_OPCODE_NOP &&
exec_list_is_singular(&block->instructions))) {