summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Turner <[email protected]>2013-10-22 15:40:08 -0700
committerMatt Turner <[email protected]>2013-10-30 19:49:27 -0700
commit219b43c612b2882e0bf82ac1a12ff073a42be6e1 (patch)
treeb1a7abaeee0d10a86d75f7d5f58430001d163643
parenta93d54eb68f8c73ed65e4a7e861b810a9111c5a4 (diff)
i965/fs: Don't emit null MOVs in CSE.
We'd like to CSE some instructions, like CMP, that often have null destinations. Instead of replacing them with MOVs to null, just don't emit the MOV. Reviewed-by: Paul Berry <[email protected]>
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs_cse.cpp42
1 files changed, 25 insertions, 17 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs_cse.cpp b/src/mesa/drivers/dri/i965/brw_fs_cse.cpp
index 0afc5f65f6e..3f59339f716 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_cse.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_cse.cpp
@@ -150,7 +150,7 @@ fs_visitor::opt_cse_local(bblock_t *block, exec_list *aeb)
* If we don't have a temporary already, make one.
*/
bool no_existing_temp = entry->tmp.file == BAD_FILE;
- if (no_existing_temp) {
+ if (no_existing_temp && !entry->generator->dst.is_null()) {
int written = entry->generator->regs_written;
fs_reg orig_dst = entry->generator->dst;
@@ -171,29 +171,37 @@ fs_visitor::opt_cse_local(bblock_t *block, exec_list *aeb)
}
/* dest <- temp */
- int written = inst->regs_written;
- assert(written == entry->generator->regs_written);
- assert(inst->dst.type == entry->tmp.type);
- fs_reg dst = inst->dst;
- fs_reg tmp = entry->tmp;
- fs_inst *copy = NULL;
- for (int i = 0; i < written; i++) {
- copy = MOV(dst, tmp);
- copy->force_writemask_all = inst->force_writemask_all;
- inst->insert_before(copy);
-
- dst.reg_offset++;
- tmp.reg_offset++;
+ if (!inst->dst.is_null()) {
+ int written = inst->regs_written;
+ assert(written == entry->generator->regs_written);
+ assert(inst->dst.type == entry->tmp.type);
+ fs_reg dst = inst->dst;
+ fs_reg tmp = entry->tmp;
+ fs_inst *copy = NULL;
+ for (int i = 0; i < written; i++) {
+ copy = MOV(dst, tmp);
+ copy->force_writemask_all = inst->force_writemask_all;
+ inst->insert_before(copy);
+
+ dst.reg_offset++;
+ tmp.reg_offset++;
+ }
}
+
+ /* Set our iterator so that next time through the loop inst->next
+ * will get the instruction in the basic block after the one we've
+ * removed.
+ */
+ fs_inst *prev = (fs_inst *)inst->prev;
+
inst->remove();
/* Appending an instruction may have changed our bblock end. */
if (inst == block->end) {
- block->end = copy;
+ block->end = prev;
}
- /* Continue iteration with copy->next */
- inst = copy;
+ inst = prev;
}
}