summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2015-06-08 16:03:19 -0700
committerJason Ekstrand <[email protected]>2015-06-24 13:11:30 -0700
commitb2c6ba0c4b21391dc35018e1c8c4f7f7d8952bea (patch)
treefbdf149b07a7b8f3af042bc21da877ab4d342dd6 /src
parent104c8fc2c2aa5621261f80aa6b4f76c3163078f1 (diff)
i965/fs_live_variables: Do liveness analysis bottom-to-top
From Muchnick's Advanced Compiler Design and Implementation: "To determine which variables are live at each point in a flowgraph, we perform a backward data-flow analysis" Previously, we were walking the blocks forwards and updating the livein and then the liveout. However, the livein calculation depends on the liveout and the liveout depends on the successor blocks. The net result is that it takes one full iteration to go from liveout to livein and then another full iteration to propagate to the predecessors. This works out to an O(n^2) computation where n is the number of blocks. If we run things in the other order, it's O(nl) where l is the maximum loop depth which is practically bounded by 3. On my HSW desktop, one particular shadertoy test gets a 20% improvement in compile times: N Min Max Median Avg Stddev x 10 15.965 16.884 16.026 16.1822 0.34736846 + 10 12.813 13.052 12.876 12.8891 0.06913666 Difference at 95.0% confidence -3.2931 +/- 0.235316 -20.3501% +/- 1.45417% (Student's t, pooled s = 0.250444) Reviewed-by: Matt Turner <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp38
1 files changed, 19 insertions, 19 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 502161d5128..19aec92fad1 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_live_variables.cpp
@@ -204,27 +204,9 @@ fs_live_variables::compute_live_variables()
while (cont) {
cont = false;
- foreach_block (block, cfg) {
+ foreach_block_reverse (block, cfg) {
struct block_data *bd = &block_data[block->num];
- /* Update livein */
- for (int i = 0; i < bitset_words; i++) {
- BITSET_WORD new_livein = (bd->use[i] |
- (bd->liveout[i] &
- ~bd->def[i]));
- if (new_livein & ~bd->livein[i]) {
- bd->livein[i] |= new_livein;
- cont = true;
- }
- }
- BITSET_WORD new_livein = (bd->flag_use[0] |
- (bd->flag_liveout[0] &
- ~bd->flag_def[0]));
- if (new_livein & ~bd->flag_livein[0]) {
- bd->flag_livein[0] |= new_livein;
- cont = true;
- }
-
/* Update liveout */
foreach_list_typed(bblock_link, child_link, link, &block->children) {
struct block_data *child_bd = &block_data[child_link->block->num];
@@ -244,6 +226,24 @@ fs_live_variables::compute_live_variables()
cont = true;
}
}
+
+ /* Update livein */
+ for (int i = 0; i < bitset_words; i++) {
+ BITSET_WORD new_livein = (bd->use[i] |
+ (bd->liveout[i] &
+ ~bd->def[i]));
+ if (new_livein & ~bd->livein[i]) {
+ bd->livein[i] |= new_livein;
+ cont = true;
+ }
+ }
+ BITSET_WORD new_livein = (bd->flag_use[0] |
+ (bd->flag_liveout[0] &
+ ~bd->flag_def[0]));
+ if (new_livein & ~bd->flag_livein[0]) {
+ bd->flag_livein[0] |= new_livein;
+ cont = true;
+ }
}
}
}