From 0fec265373f269d116f6d4de900b208fffabe2a1 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Wed, 18 May 2016 21:34:27 -0700 Subject: [PATCH] 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 --- .../dri/i965/brw_fs_dead_code_eliminate.cpp | 11 ++++----- .../dri/i965/brw_fs_live_variables.cpp | 23 ++++--------------- 2 files changed, 9 insertions(+), 25 deletions(-) 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++; } -- 2.30.2