diff options
author | Matt Turner <[email protected]> | 2014-03-11 13:16:37 -0700 |
---|---|---|
committer | Matt Turner <[email protected]> | 2014-03-24 11:06:26 -0700 |
commit | 9cd51bb0c4608258199c69bc7738e72f055799d2 (patch) | |
tree | ec2a160a77dab3b2e573c39859927ac3bfda4c10 | |
parent | 1b8f143a2302739de90cb643d732e12b55d4e4eb (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.cpp | 46 |
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) |