summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/intel/compiler/brw_fs_live_variables.cpp34
-rw-r--r--src/intel/compiler/brw_fs_live_variables.h12
2 files changed, 42 insertions, 4 deletions
diff --git a/src/intel/compiler/brw_fs_live_variables.cpp b/src/intel/compiler/brw_fs_live_variables.cpp
index c449672a519..059f076fa51 100644
--- a/src/intel/compiler/brw_fs_live_variables.cpp
+++ b/src/intel/compiler/brw_fs_live_variables.cpp
@@ -83,9 +83,11 @@ fs_live_variables::setup_one_write(struct block_data *bd, 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 == VGRF && !inst->is_partial_write()) {
- if (!BITSET_TEST(bd->use, var))
+ if (inst->dst.file == VGRF) {
+ if (!inst->is_partial_write() && !BITSET_TEST(bd->use, var))
BITSET_SET(bd->def, var);
+
+ BITSET_SET(bd->defout, var);
}
}
@@ -199,6 +201,28 @@ fs_live_variables::compute_live_variables()
}
}
}
+
+ /* Propagate defin and defout down the CFG to calculate the union of live
+ * variables potentially defined along any possible control flow path.
+ */
+ do {
+ cont = false;
+
+ foreach_block (block, cfg) {
+ const struct block_data *bd = &block_data[block->num];
+
+ foreach_list_typed(bblock_link, child_link, link, &block->children) {
+ struct block_data *child_bd = &block_data[child_link->block->num];
+
+ for (int i = 0; i < bitset_words; i++) {
+ const BITSET_WORD new_def = bd->defout[i] & ~child_bd->defin[i];
+ child_bd->defin[i] |= new_def;
+ child_bd->defout[i] |= new_def;
+ cont |= new_def;
+ }
+ }
+ }
+ } while (cont);
}
/**
@@ -212,12 +236,12 @@ fs_live_variables::compute_start_end()
struct block_data *bd = &block_data[block->num];
for (int i = 0; i < num_vars; i++) {
- if (BITSET_TEST(bd->livein, i)) {
+ if (BITSET_TEST(bd->livein, i) && BITSET_TEST(bd->defin, i)) {
start[i] = MIN2(start[i], block->start_ip);
end[i] = MAX2(end[i], block->start_ip);
}
- if (BITSET_TEST(bd->liveout, i)) {
+ if (BITSET_TEST(bd->liveout, i) && BITSET_TEST(bd->defout, i)) {
start[i] = MIN2(start[i], block->end_ip);
end[i] = MAX2(end[i], block->end_ip);
}
@@ -260,6 +284,8 @@ fs_live_variables::fs_live_variables(fs_visitor *v, const cfg_t *cfg)
block_data[i].use = rzalloc_array(mem_ctx, BITSET_WORD, bitset_words);
block_data[i].livein = rzalloc_array(mem_ctx, BITSET_WORD, bitset_words);
block_data[i].liveout = rzalloc_array(mem_ctx, BITSET_WORD, bitset_words);
+ block_data[i].defin = rzalloc_array(mem_ctx, BITSET_WORD, bitset_words);
+ block_data[i].defout = rzalloc_array(mem_ctx, BITSET_WORD, bitset_words);
block_data[i].flag_def[0] = 0;
block_data[i].flag_use[0] = 0;
diff --git a/src/intel/compiler/brw_fs_live_variables.h b/src/intel/compiler/brw_fs_live_variables.h
index d2d5898ed1c..9e95e443170 100644
--- a/src/intel/compiler/brw_fs_live_variables.h
+++ b/src/intel/compiler/brw_fs_live_variables.h
@@ -55,6 +55,18 @@ struct block_data {
/** Which defs reach the exit point of the block. */
BITSET_WORD *liveout;
+ /**
+ * Variables such that the entry point of the block may be reached from any
+ * of their definitions.
+ */
+ BITSET_WORD *defin;
+
+ /**
+ * Variables such that the exit point of the block may be reached from any
+ * of their definitions.
+ */
+ BITSET_WORD *defout;
+
BITSET_WORD flag_def[1];
BITSET_WORD flag_use[1];
BITSET_WORD flag_livein[1];