summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2013-02-19 16:20:10 -0800
committerEric Anholt <[email protected]>2013-03-11 12:11:54 -0700
commit5daf867f6c8984e6e025d8a0b0a7dfa162068420 (patch)
treede7ac6db9f1906acef6d77e6c9fd6bff9e039716 /src/mesa
parentf179f419d1d0a03fad36c2b0a58e8b853bae6118 (diff)
i965/fs: Improve CSE performance by expiring some available expressions.
We're already walking the list, and we can easily know when something has no reason to be in the list any longer, so take a brief extra step to reduce our worst-case runtime (an oglconform test that emits the maximum instructions in a fragment program). I don't actually know what the worst-case runtime was, because it was too long and I got bored. Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_cse.cpp20
1 files changed, 19 insertions, 1 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs_cse.cpp b/src/mesa/drivers/dri/i965/brw_fs_cse.cpp
index e0f824c5e3e..02642c91a61 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_cse.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_cse.cpp
@@ -89,6 +89,7 @@ fs_visitor::opt_cse_local(bblock_t *block, exec_list *aeb)
void *mem_ctx = ralloc_context(this->mem_ctx);
+ int ip = block->start_ip;
for (fs_inst *inst = (fs_inst *)block->start;
inst != block->end->next;
inst = (fs_inst *) inst->next) {
@@ -154,18 +155,33 @@ fs_visitor::opt_cse_local(bblock_t *block, exec_list *aeb)
}
}
- /* Kill all AEB entries that use the destination. */
foreach_list_safe(entry_node, aeb) {
aeb_entry *entry = (aeb_entry *)entry_node;
for (int i = 0; i < 3; i++) {
+ fs_reg *src_reg = &entry->generator->src[i];
+
+ /* Kill all AEB entries that use the destination we just
+ * overwrote.
+ */
if (inst->overwrites_reg(entry->generator->src[i])) {
entry->remove();
ralloc_free(entry);
break;
}
+
+ /* Kill any AEB entries using registers that don't get reused any
+ * more -- a sure sign they'll fail operands_match().
+ */
+ if (src_reg->file == GRF && virtual_grf_use[src_reg->reg] < ip) {
+ entry->remove();
+ ralloc_free(entry);
+ break;
+ }
}
}
+
+ ip++;
}
ralloc_free(mem_ctx);
@@ -181,6 +197,8 @@ fs_visitor::opt_cse()
{
bool progress = false;
+ calculate_live_intervals();
+
cfg_t cfg(this);
for (int b = 0; b < cfg.num_blocks; b++) {