Mesa (master): i965/fs: Improve CSE performance by expiring some available expressions.

Eric Anholt anholt at kemper.freedesktop.org
Mon Mar 11 19:28:31 UTC 2013


Module: Mesa
Branch: master
Commit: 5daf867f6c8984e6e025d8a0b0a7dfa162068420
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=5daf867f6c8984e6e025d8a0b0a7dfa162068420

Author: Eric Anholt <eric at anholt.net>
Date:   Tue Feb 19 16:20:10 2013 -0800

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 <kenneth at whitecape.org>

---

 src/mesa/drivers/dri/i965/brw_fs_cse.cpp |   20 +++++++++++++++++++-
 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 e0f824c..02642c9 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++) {




More information about the mesa-commit mailing list