diff options
author | Eric Anholt <[email protected]> | 2013-02-19 16:20:10 -0800 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2013-03-11 12:11:54 -0700 |
commit | 5daf867f6c8984e6e025d8a0b0a7dfa162068420 (patch) | |
tree | de7ac6db9f1906acef6d77e6c9fd6bff9e039716 /src/mesa | |
parent | f179f419d1d0a03fad36c2b0a58e8b853bae6118 (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.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 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++) { |