From: Francisco Jerez Date: Thu, 19 May 2016 04:34:27 +0000 (-0700) Subject: i965/fs: Track flag register liveness with byte granularity. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0fec265373f269d116f6d4de900b208fffabe2a1;p=mesa.git 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 --- diff --git a/src/mesa/drivers/dri/i965/brw_fs_dead_code_eliminate.cpp b/src/mesa/drivers/dri/i965/brw_fs_dead_code_eliminate.cpp index bd57e09fe0c..a1d07ff3e8e 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_dead_code_eliminate.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_dead_code_eliminate.cpp @@ -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); } } diff --git a/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp b/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp index 66b70a9144b..8bd42298a23 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp @@ -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++; }