[Mesa-dev] [PATCHv3 1/3] i965/fs: improve liveness analysis for partial writes
Chia-I Wu
olvaffe at gmail.com
Wed Oct 16 08:58:09 CEST 2013
From: Chia-I Wu <olv at lunarg.com>
When two partial writes write the first and second halves of a variable
respectively before the variable is used, the variable can be added to the def
bitset.
v2: no change
v3: no longer rely on hints from by the visitor
Signed-off-by: Chia-I Wu <olv at lunarg.com>
---
.../drivers/dri/i965/brw_fs_live_variables.cpp | 26 +++++++++++++++++-----
src/mesa/drivers/dri/i965/brw_fs_live_variables.h | 5 +++--
2 files changed, 24 insertions(+), 7 deletions(-)
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 b3026c2..cceff42 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp
@@ -97,7 +97,8 @@ fs_live_variables::setup_one_read(bblock_t *block, fs_inst *inst,
* channel) without having completely defined that variable within the
* block.
*/
- if (!BITSET_TEST(bd[block->block_num].def, var))
+ if (!BITSET_TEST(bd[block->block_num].def, var) &&
+ !BITSET_TEST(bd[block->block_num].def_sechalf, var))
BITSET_SET(bd[block->block_num].use, var);
}
@@ -113,9 +114,22 @@ fs_live_variables::setup_one_write(bblock_t *block, fs_inst *inst,
/* The def[] bitset marks when an initialization in a block completely
* screens off previous updates of that variable (VGRF channel).
*/
- if (inst->dst.file == GRF && !inst->is_partial_write()) {
- if (!BITSET_TEST(bd[block->block_num].use, var))
- BITSET_SET(bd[block->block_num].def, var);
+ if (inst->dst.file == GRF) {
+ /* We do not want to call inst->is_partial_write() here as we track the
+ * two halves separately.
+ */
+ bool predicated = (inst->predicate && inst->opcode != BRW_OPCODE_SEL);
+
+ if (!predicated && !BITSET_TEST(bd[block->block_num].use, var)) {
+ if (inst->force_sechalf) {
+ BITSET_SET(bd[block->block_num].def_sechalf, var);
+ } else {
+ BITSET_SET(bd[block->block_num].def, var);
+
+ if (!inst->force_uncompressed)
+ BITSET_SET(bd[block->block_num].def_sechalf, var);
+ }
+ }
}
}
@@ -188,8 +202,9 @@ fs_live_variables::compute_live_variables()
for (int b = 0; b < cfg->num_blocks; b++) {
/* Update livein */
for (int i = 0; i < bitset_words; i++) {
+ BITSET_WORD def = (bd[b].def[i] & bd[b].def_sechalf[i]);
BITSET_WORD new_livein = (bd[b].use[i] |
- (bd[b].liveout[i] & ~bd[b].def[i]));
+ (bd[b].liveout[i] & ~def));
if (new_livein & ~bd[b].livein[i]) {
bd[b].livein[i] |= new_livein;
cont = true;
@@ -275,6 +290,7 @@ fs_live_variables::fs_live_variables(fs_visitor *v, cfg_t *cfg)
bitset_words = BITSET_WORDS(num_vars);
for (int i = 0; i < cfg->num_blocks; i++) {
bd[i].def = rzalloc_array(mem_ctx, BITSET_WORD, bitset_words);
+ bd[i].def_sechalf = rzalloc_array(mem_ctx, BITSET_WORD, bitset_words);
bd[i].use = rzalloc_array(mem_ctx, BITSET_WORD, bitset_words);
bd[i].livein = rzalloc_array(mem_ctx, BITSET_WORD, bitset_words);
bd[i].liveout = rzalloc_array(mem_ctx, BITSET_WORD, bitset_words);
diff --git a/src/mesa/drivers/dri/i965/brw_fs_live_variables.h b/src/mesa/drivers/dri/i965/brw_fs_live_variables.h
index 82575d8..d7f0bba 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_live_variables.h
+++ b/src/mesa/drivers/dri/i965/brw_fs_live_variables.h
@@ -37,9 +37,10 @@ struct block_data {
* Which variables are defined before being used in the block.
*
* Note that for our purposes, "defined" means unconditionally, completely
- * defined.
+ * defined. As an instruction may write to only the first or the second
+ * half of a variable, we need two bitsets.
*/
- BITSET_WORD *def;
+ BITSET_WORD *def, *def_sechalf;
/**
* Which variables are used before being defined in the block.
--
1.8.3.1
More information about the mesa-dev
mailing list