i965/fs: Separate the updating of liveout/livein.
authorKenneth Graunke <kenneth@whitecape.org>
Sat, 10 Aug 2013 00:53:05 +0000 (17:53 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Mon, 19 Aug 2013 18:29:24 +0000 (11:29 -0700)
To compute the actual liveout/livein data flow values, we start with
some initial values and apply a fixed-point algorithm until they settle.

Previously, we iterated through all blocks, updating both liveout and
livein together in one pass.  This is awkward, since computing livein
for a block requires knowing liveout for all parent blocks.  Not all
of those parent blocks may have been processed yet.

This patch separates the two.  First, we update liveout for all blocks.
At iteration N of the fixed-point algorithm, this uses livein values
from iteration N-1.  Secondly, we update livein for all blocks.  At
step N, this uses the liveout information we just computed (in step N).

This ensures each computation has a consistent picture of the data,
rather than seeing an random mix of data from steps N-1 and N depending
on the order of the blocks in the CFG data structure.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Paul Berry <stereotype441@gmail.com>
src/mesa/drivers/dri/i965/brw_fs_copy_propagation.cpp

index 055444d4c9968debec2f49ce984a800ab701e66b..144a43f85acb9ddd00c6ba3ca1f2789ed1192a00 100644 (file)
@@ -167,6 +167,7 @@ fs_copy_prop_dataflow::run()
    do {
       progress = false;
 
+      /* Update liveout for all blocks. */
       for (int b = 0; b < cfg->num_blocks; b++) {
          for (int i = 0; i < bitset_words; i++) {
             BITSET_WORD new_liveout = (bd[b].livein[i] &
@@ -176,10 +177,14 @@ fs_copy_prop_dataflow::run()
                bd[b].liveout[i] |= new_liveout;
                progress = true;
             }
+         }
+      }
 
-            /* Update livein: if it's live at the end of all parents, it's
-             * live at our start.
-             */
+      /* Update livein for all blocks.  If a copy is live out of all parent
+       * blocks, it's live coming in to this block.
+       */
+      for (int b = 0; b < cfg->num_blocks; b++) {
+         for (int i = 0; i < bitset_words; i++) {
             BITSET_WORD new_livein = ~bd[b].livein[i];
             foreach_list(block_node, &cfg->blocks[b]->parents) {
                bblock_link *link = (bblock_link *)block_node;