mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-04 17:50:11 +01:00
i965/fs: Track flag register liveness with byte granularity.
This is required for correctness in presence of multiple 8-wide flag writes (e.g. 8-wide instructions with a conditional mod set) which update a different portion of the same 16-bit flag subregister. Right now we keep track of flag dataflow with 16-bit granularity and consider flag writes to have killed any previous definition of the same subregister even if the write was less than 16 channels wide, which can cause live flag register updates to be dead code-eliminated incorrectly. Additionally this makes sure that we handle 32-wide flag writes and reads which may span multiple flag subregisters so the current approach of just setting/testing a single bit from the live set wouldn't have worked. Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
This commit is contained in:
parent
df1aec763e
commit
0fec265373
2 changed files with 9 additions and 25 deletions
|
|
@ -77,7 +77,7 @@ fs_visitor::dead_code_eliminate()
|
|||
}
|
||||
|
||||
if (inst->dst.is_null() && inst->writes_flag()) {
|
||||
if (!BITSET_TEST(flag_live, inst->flag_subreg)) {
|
||||
if (!(flag_live[0] & inst->flags_written())) {
|
||||
inst->opcode = BRW_OPCODE_NOP;
|
||||
progress = true;
|
||||
}
|
||||
|
|
@ -102,9 +102,8 @@ fs_visitor::dead_code_eliminate()
|
|||
}
|
||||
}
|
||||
|
||||
if (inst->writes_flag() && !inst->predicate) {
|
||||
BITSET_CLEAR(flag_live, inst->flag_subreg);
|
||||
}
|
||||
if (!inst->predicate && inst->exec_size >= 8)
|
||||
flag_live[0] &= ~inst->flags_written();
|
||||
|
||||
if (inst->opcode == BRW_OPCODE_NOP) {
|
||||
inst->remove(block);
|
||||
|
|
@ -121,9 +120,7 @@ fs_visitor::dead_code_eliminate()
|
|||
}
|
||||
}
|
||||
|
||||
if (inst->reads_flag()) {
|
||||
BITSET_SET(flag_live, inst->flag_subreg);
|
||||
}
|
||||
flag_live[0] |= inst->flags_read(devinfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -123,19 +123,8 @@ fs_live_variables::setup_def_use()
|
|||
reg.reg_offset++;
|
||||
}
|
||||
}
|
||||
if (inst->reads_flag()) {
|
||||
/* The vertical combination predicates read f0.0 and f0.1. */
|
||||
if (inst->predicate == BRW_PREDICATE_ALIGN1_ANYV ||
|
||||
inst->predicate == BRW_PREDICATE_ALIGN1_ALLV) {
|
||||
assert(inst->flag_subreg == 0);
|
||||
if (!BITSET_TEST(bd->flag_def, 1)) {
|
||||
BITSET_SET(bd->flag_use, 1);
|
||||
}
|
||||
}
|
||||
if (!BITSET_TEST(bd->flag_def, inst->flag_subreg)) {
|
||||
BITSET_SET(bd->flag_use, inst->flag_subreg);
|
||||
}
|
||||
}
|
||||
|
||||
bd->flag_use[0] |= inst->flags_read(v->devinfo) & ~bd->flag_def[0];
|
||||
|
||||
/* Set def[] for this instruction */
|
||||
if (inst->dst.file == VGRF) {
|
||||
|
|
@ -145,11 +134,9 @@ fs_live_variables::setup_def_use()
|
|||
reg.reg_offset++;
|
||||
}
|
||||
}
|
||||
if (inst->writes_flag()) {
|
||||
if (!BITSET_TEST(bd->flag_use, inst->flag_subreg)) {
|
||||
BITSET_SET(bd->flag_def, inst->flag_subreg);
|
||||
}
|
||||
}
|
||||
|
||||
if (!inst->predicate && inst->exec_size >= 8)
|
||||
bd->flag_def[0] |= inst->flags_written() & ~bd->flag_use[0];
|
||||
|
||||
ip++;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue