summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Turner <[email protected]>2014-03-11 13:16:37 -0700
committerMatt Turner <[email protected]>2014-03-24 11:06:26 -0700
commit9cd51bb0c4608258199c69bc7738e72f055799d2 (patch)
treeec2a160a77dab3b2e573c39859927ac3bfda4c10
parent1b8f143a2302739de90cb643d732e12b55d4e4eb (diff)
i965/vec4: Eliminate writes that are never read.
With an awful O(n^2) algorithm that searches previous instructions for dead writes. total instructions in shared programs: 805582 -> 788074 (-2.17%) instructions in affected programs: 144561 -> 127053 (-12.11%) Reviewed-by: Eric Anholt <[email protected]>
-rw-r--r--src/mesa/drivers/dri/i965/brw_vec4.cpp46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp b/src/mesa/drivers/dri/i965/brw_vec4.cpp
index 4ad398af90b..e9219a9aa5e 100644
--- a/src/mesa/drivers/dri/i965/brw_vec4.cpp
+++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp
@@ -369,6 +369,7 @@ bool
vec4_visitor::dead_code_eliminate()
{
bool progress = false;
+ bool seen_control_flow = false;
int pc = -1;
calculate_live_intervals();
@@ -378,6 +379,8 @@ vec4_visitor::dead_code_eliminate()
pc++;
+ seen_control_flow = inst->is_control_flow() || seen_control_flow;
+
if (inst->dst.file != GRF || inst->has_side_effects())
continue;
@@ -393,6 +396,49 @@ vec4_visitor::dead_code_eliminate()
}
progress = try_eliminate_instruction(inst, write_mask) || progress;
+
+ if (seen_control_flow || inst->predicate || inst->prev == NULL)
+ continue;
+
+ int 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 j = 0; j < 4; j++) {
+ int swiz = BRW_GET_SWZ(inst->src[i].swizzle, j);
+ dead_channels &= ~(1 << swiz);
+ }
+ }
+
+ for (exec_node *node = inst->prev, *prev = node->prev;
+ prev != NULL && dead_channels != 0;
+ node = prev, prev = prev->prev) {
+ vec4_instruction *scan_inst = (vec4_instruction *)node;
+
+ if (scan_inst->dst.file != GRF || scan_inst->has_side_effects())
+ continue;
+
+ if (inst->dst.reg == scan_inst->dst.reg) {
+ int new_writemask = scan_inst->dst.writemask & ~dead_channels;
+
+ progress = try_eliminate_instruction(scan_inst, new_writemask) ||
+ progress;
+ }
+
+ for (int i = 0; i < 3; i++) {
+ if (scan_inst->src[i].file != GRF ||
+ scan_inst->src[i].reg != inst->dst.reg)
+ continue;
+
+ for (int j = 0; j < 4; j++) {
+ int swiz = BRW_GET_SWZ(scan_inst->src[i].swizzle, j);
+ dead_channels &= ~(1 << swiz);
+ }
+ }
+ }
}
if (progress)