From: Matt Turner Date: Tue, 11 Mar 2014 20:16:37 +0000 (-0700) Subject: i965/vec4: Eliminate writes that are never read. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9cd51bb0c4608258199c69bc7738e72f055799d2;p=mesa.git 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 --- 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)