summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Turner <mattst88@gmail.com>2014-03-18 19:19:02 -0700
committerMatt Turner <mattst88@gmail.com>2014-03-24 11:06:26 -0700
commit764e25d79dad3096274ab2df04f5aa3ffb232119 (patch)
tree632d9fcf1e59ed60f9f7ce789d577ff008d2f3c1
parent9cd51bb0c4608258199c69bc7738e72f055799d2 (diff)
i965/vec4: Eliminate dead writes to the flag register.
For each write, search previous instructions for unread writes to the flag register and remove them. Note that this will not eliminate the last unread write. total instructions in shared programs: 788074 -> 788004 (-0.01%) instructions in affected programs: 4930 -> 4860 (-1.42%) Reviewed-by: Eric Anholt <eric@anholt.net>
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4.cpp66
1 files changed, 48 insertions, 18 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp b/src/mesa/drivers/dri/i965/brw_vec4.cpp
index e9219a9aa5..4ae60208f2 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp
@@ -381,35 +381,53 @@ vec4_visitor::dead_code_eliminate()
seen_control_flow = inst->is_control_flow() || seen_control_flow;
- if (inst->dst.file != GRF || inst->has_side_effects())
+ if (inst->has_side_effects())
continue;
- int write_mask = inst->dst.writemask;
+ bool inst_writes_flag = false;
+ if (inst->dst.file != GRF) {
+ if (inst->dst.is_null() && inst->writes_flag()) {
+ inst_writes_flag = true;
+ } else {
+ continue;
+ }
+ }
- for (int c = 0; c < 4; c++) {
- if (write_mask & (1 << c)) {
- assert(this->virtual_grf_end[inst->dst.reg * 4 + c] >= pc);
- if (this->virtual_grf_end[inst->dst.reg * 4 + c] == pc) {
- write_mask &= ~(1 << c);
+ if (inst->dst.file == GRF) {
+ int write_mask = inst->dst.writemask;
+
+ for (int c = 0; c < 4; c++) {
+ if (write_mask & (1 << c)) {
+ assert(this->virtual_grf_end[inst->dst.reg * 4 + c] >= pc);
+ if (this->virtual_grf_end[inst->dst.reg * 4 + c] == pc) {
+ write_mask &= ~(1 << c);
+ }
}
}
- }
- progress = try_eliminate_instruction(inst, write_mask) || progress;
+ progress = try_eliminate_instruction(inst, write_mask) || progress;
+ }
if (seen_control_flow || inst->predicate || inst->prev == NULL)
continue;
- int dead_channels = inst->dst.writemask;
+ int dead_channels;
+ if (inst_writes_flag) {
+/* Arbitrarily chosen, other than not being an xyzw writemask. */
+#define FLAG_WRITEMASK (1 << 5)
+ dead_channels = inst->reads_flag() ? 0 : FLAG_WRITEMASK;
+ } else {
+ dead_channels = inst->dst.writemask;
- for (int i = 0; i < 3; i++) {
- if (inst->src[i].file != GRF ||
- inst->src[i].reg != inst->dst.reg)
- continue;
+ for (int i = 0; i < 3; i++) {
+ if (inst->src[i].file != GRF ||
+ inst->src[i].reg != inst->dst.reg)
+ continue;
- for (int j = 0; j < 4; j++) {
- int swiz = BRW_GET_SWZ(inst->src[i].swizzle, j);
- dead_channels &= ~(1 << swiz);
+ for (int j = 0; j < 4; j++) {
+ int swiz = BRW_GET_SWZ(inst->src[i].swizzle, j);
+ dead_channels &= ~(1 << swiz);
+ }
}
}
@@ -418,9 +436,21 @@ vec4_visitor::dead_code_eliminate()
node = prev, prev = prev->prev) {
vec4_instruction *scan_inst = (vec4_instruction *)node;
- if (scan_inst->dst.file != GRF || scan_inst->has_side_effects())
+ if (scan_inst->has_side_effects())
continue;
+ if (inst_writes_flag) {
+ if (scan_inst->dst.is_null() && scan_inst->writes_flag()) {
+ scan_inst->remove();
+ progress = true;
+ } else if (scan_inst->reads_flag()) {
+ dead_channels = 0;
+ }
+ continue;
+ } else if (scan_inst->dst.file != GRF) {
+ continue;
+ }
+
if (inst->dst.reg == scan_inst->dst.reg) {
int new_writemask = scan_inst->dst.writemask & ~dead_channels;