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. --- src/mesa/drivers/dri/i965/brw_fs_cse.cpp | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/src/mesa/drivers/dri/i965/brw_fs_cse.cpp b/src/mesa/drivers/dri/i965/brw_fs_cse.cpp index 44479d8..09c7fa6 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_cse.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_cse.cpp @@ -88,6 +88,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) { @@ -153,18 +154,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); @@ -180,6 +196,8 @@ fs_visitor::opt_cse() { bool progress = false; + calculate_live_intervals(); + cfg_t cfg(this); for (int b = 0; b < cfg.num_blocks; b++) { -- 1.7.10.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev