summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2013-03-22 14:11:25 -0700
committerEric Anholt <eric@anholt.net>2013-03-28 09:48:50 -0700
commiteda434921d6d7980f8b116e4ebde2da6553b9094 (patch)
treebdf51c6bd6470265922cb0843aae990a2106c5cf
parentd066133a7637864bde46b8118778c526826583a6 (diff)
i965/fs: Improve performance of copy propagation dataflow using bitsets.
Reduces compile time of l4d2's slowest shader by 17.8% +/- 1.3% (n=10). Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp67
1 files changed, 34 insertions, 33 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp b/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp
index 194ed07cb3f..ec72ede87b9 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp
@@ -36,2 +36,3 @@
+#include "main/bitset.h"
#include "brw_fs.h"
@@ -52,3 +53,3 @@ struct block_data {
*/
- bool *livein;
+ BITSET_WORD *livein;
@@ -59,3 +60,3 @@ struct block_data {
*/
- bool *liveout;
+ BITSET_WORD *liveout;
@@ -65,3 +66,3 @@ struct block_data {
*/
- bool *kill;
+ BITSET_WORD *kill;
};
@@ -82,2 +83,3 @@ public:
int num_acp;
+ int bitset_words;
@@ -104,7 +106,9 @@ fs_copy_prop_dataflow::fs_copy_prop_dataflow(void *mem_ctx, cfg_t *cfg,
+ bitset_words = ALIGN(num_acp, BITSET_WORDBITS) / BITSET_WORDBITS;
+
int next_acp = 0;
for (int b = 0; b < cfg->num_blocks; b++) {
- bd[b].livein = rzalloc_array(bd, bool, num_acp);
- bd[b].liveout = rzalloc_array(bd, bool, num_acp);
- bd[b].kill = rzalloc_array(bd, bool, num_acp);
+ bd[b].livein = rzalloc_array(bd, BITSET_WORD, bitset_words);
+ bd[b].liveout = rzalloc_array(bd, BITSET_WORD, bitset_words);
+ bd[b].kill = rzalloc_array(bd, BITSET_WORD, bitset_words);
@@ -115,3 +119,3 @@ fs_copy_prop_dataflow::fs_copy_prop_dataflow(void *mem_ctx, cfg_t *cfg,
acp[next_acp] = entry;
- bd[b].liveout[next_acp] = true;
+ BITSET_SET(bd[b].liveout, next_acp);
next_acp++;
@@ -146,3 +150,3 @@ fs_copy_prop_dataflow::setup_kills()
inst->overwrites_reg(acp[i]->src)) {
- bd[b].kill[i] = true;
+ BITSET_SET(bd[b].kill, i);
}
@@ -166,28 +170,25 @@ fs_copy_prop_dataflow::run()
for (int b = 0; b < cfg->num_blocks; b++) {
- for (int i = 0; i < num_acp; i++) {
- if (!bd[b].liveout[i]) {
- /* Update liveout */
- if (bd[b].livein[i] && !bd[b].kill[i]) {
- bd[b].liveout[i] = true;
- cont = true;
- }
+ for (int i = 0; i < bitset_words; i++) {
+ BITSET_WORD new_liveout = (bd[b].livein[i] &
+ ~bd[b].kill[i] &
+ ~bd[b].liveout[i]);
+ if (new_liveout) {
+ bd[b].liveout[i] |= new_liveout;
+ cont = true;
}
- if (!bd[b].livein[i]) {
- /* Update livein: if it's live at the end of all parents, it's
- * live at our start.
- */
- bool add = true;
- foreach_list(block_node, &cfg->blocks[b]->parents) {
- bblock_link *link = (bblock_link *)block_node;
- bblock_t *block = link->block;
- if (!bd[block->block_num].liveout[i]) {
- add = false;
- break;
- }
- }
- if (add) {
- bd[b].livein[i] = true;
- cont = true;
- }
+ /* Update livein: if it's live at the end of all parents, it's
+ * live at our start.
+ */
+ BITSET_WORD new_livein = ~bd[b].livein[i];
+ foreach_list(block_node, &cfg->blocks[b]->parents) {
+ bblock_link *link = (bblock_link *)block_node;
+ bblock_t *block = link->block;
+ new_livein &= bd[block->block_num].liveout[i];
+ if (!new_livein)
+ break;
+ }
+ if (new_livein) {
+ bd[b].livein[i] |= new_livein;
+ cont = true;
}
@@ -457,3 +458,3 @@ fs_visitor::opt_copy_propagate()
for (int i = 0; i < dataflow.num_acp; i++) {
- if (dataflow.bd[b].livein[i]) {
+ if (BITSET_TEST(dataflow.bd[b].livein, i)) {
struct acp_entry *entry = dataflow.acp[i];