+ if (inst->predicate || inst->prev == NULL)
+ continue;
+
+ 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 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->is_control_flow())
+ break;
+
+ if (inst_writes_flag) {
+ if (scan_inst->dst.is_null() && scan_inst->writes_flag()) {
+ scan_inst->remove();
+ progress = true;
+ continue;
+ } else if (scan_inst->reads_flag()) {
+ break;
+ }
+ }
+
+ if (inst->dst.file == scan_inst->dst.file &&
+ inst->dst.reg == scan_inst->dst.reg &&
+ inst->dst.reg_offset == scan_inst->dst.reg_offset) {
+ int new_writemask = scan_inst->dst.writemask & ~dead_channels;
+
+ progress = try_eliminate_instruction(scan_inst, new_writemask, brw) ||
+ progress;
+ }
+
+ for (int i = 0; i < 3; i++) {
+ if (scan_inst->src[i].file != inst->dst.file ||
+ 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);
+ }
+ }
+ }