From f0598d413bc8eb7ab02318f1db2dbd446a3c736c Mon Sep 17 00:00:00 2001 From: Matt Turner Date: Tue, 2 Sep 2014 10:08:24 -0700 Subject: [PATCH] i965/fs: Don't iterate between blocks with inst->next/prev. When instruction lists are per-basic block, this won't work. Reviewed-by: Topi Pohjolainen --- .../dri/i965/brw_dead_control_flow.cpp | 5 ++- src/mesa/drivers/dri/i965/brw_fs.cpp | 20 +++------ .../i965/brw_fs_peephole_predicated_break.cpp | 7 +++- .../dri/i965/brw_fs_saturate_propagation.cpp | 7 +--- .../drivers/dri/i965/brw_fs_sel_peephole.cpp | 42 +++++++++---------- 5 files changed, 34 insertions(+), 47 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_dead_control_flow.cpp b/src/mesa/drivers/dri/i965/brw_dead_control_flow.cpp index 485ab91b4e6..fad1d423cee 100644 --- a/src/mesa/drivers/dri/i965/brw_dead_control_flow.cpp +++ b/src/mesa/drivers/dri/i965/brw_dead_control_flow.cpp @@ -52,13 +52,14 @@ dead_control_flow_eliminate(backend_visitor *v) continue; backend_instruction *if_inst = NULL, *else_inst = NULL; - backend_instruction *prev_inst = (backend_instruction *) endif_inst->prev; + backend_instruction *prev_inst = ((bblock_t *)endif_block->link.prev)->end; if (prev_inst->opcode == BRW_OPCODE_ELSE) { else_inst = prev_inst; else_block = (bblock_t *)endif_block->link.prev; found = true; - prev_inst = (backend_instruction *) prev_inst->prev; + if (else_block->start_ip == else_block->end_ip) + prev_inst = ((bblock_t *)else_block->link.prev)->end; } if (prev_inst->opcode == BRW_OPCODE_IF) { diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index e3bb807f9cb..323abff6744 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -2213,10 +2213,7 @@ fs_visitor::compute_to_mrf() /* Found a move of a GRF to a MRF. Let's see if we can go * rewrite the thing that made this GRF to write into the MRF. */ - fs_inst *scan_inst; - for (scan_inst = (fs_inst *)inst->prev; - !scan_inst->is_head_sentinel(); - scan_inst = (fs_inst *)scan_inst->prev) { + foreach_inst_in_block_reverse_starting_from(fs_inst, scan_inst, inst, block) { if (scan_inst->dst.file == GRF && scan_inst->dst.reg == inst->src[0].reg) { /* Found the last thing to write our reg we want to turn @@ -2265,7 +2262,7 @@ fs_visitor::compute_to_mrf() * values that end up in MRFs are shortly before the MRF * write anyway. */ - if (scan_inst->is_control_flow() && scan_inst->opcode != BRW_OPCODE_IF) + if (block->start == scan_inst) break; /* You can't read from an MRF, so if someone else reads our @@ -2565,14 +2562,11 @@ fs_visitor::insert_gen4_pre_send_dependency_workarounds(bblock_t *block, * we assume that there are no outstanding dependencies on entry to the * program. */ - for (fs_inst *scan_inst = (fs_inst *)inst->prev; - !scan_inst->is_head_sentinel(); - scan_inst = (fs_inst *)scan_inst->prev) { - + foreach_inst_in_block_reverse_starting_from(fs_inst, scan_inst, inst, block) { /* If we hit control flow, assume that there *are* outstanding * dependencies, and force their cleanup before our instruction. */ - if (scan_inst->is_control_flow()) { + if (block->start == scan_inst) { for (int i = 0; i < write_len; i++) { if (needs_dep[i]) { inst->insert_before(block, DEP_RESOLVE_MOV(first_write_grf + i)); @@ -2639,11 +2633,9 @@ fs_visitor::insert_gen4_post_send_dependency_workarounds(bblock_t *block, fs_ins /* Walk forwards looking for writes to registers we're writing which aren't * read before being written. */ - for (fs_inst *scan_inst = (fs_inst *)inst->next; - !scan_inst->is_tail_sentinel(); - scan_inst = (fs_inst *)scan_inst->next) { + foreach_inst_in_block_starting_from(fs_inst, scan_inst, inst, block) { /* If we hit control flow, force resolve all remaining dependencies. */ - if (scan_inst->is_control_flow()) { + if (block->end == scan_inst) { for (int i = 0; i < write_len; i++) { if (needs_dep[i]) scan_inst->insert_before(block, diff --git a/src/mesa/drivers/dri/i965/brw_fs_peephole_predicated_break.cpp b/src/mesa/drivers/dri/i965/brw_fs_peephole_predicated_break.cpp index c669fbed9f0..5b4cab53902 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_peephole_predicated_break.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_peephole_predicated_break.cpp @@ -46,6 +46,9 @@ fs_visitor::opt_peephole_predicated_break() bool progress = false; foreach_block (block, cfg) { + if (block->start_ip != block->end_ip) + continue; + /* BREAK and CONTINUE instructions, by definition, can only be found at * the ends of basic blocks. */ @@ -54,11 +57,11 @@ fs_visitor::opt_peephole_predicated_break() jump_inst->opcode != BRW_OPCODE_CONTINUE) continue; - fs_inst *if_inst = (fs_inst *)jump_inst->prev; + fs_inst *if_inst = (fs_inst *)((bblock_t *)block->link.prev)->end; if (if_inst->opcode != BRW_OPCODE_IF) continue; - fs_inst *endif_inst = (fs_inst *)jump_inst->next; + fs_inst *endif_inst = (fs_inst *)((bblock_t *)block->link.next)->start; if (endif_inst->opcode != BRW_OPCODE_ENDIF) continue; diff --git a/src/mesa/drivers/dri/i965/brw_fs_saturate_propagation.cpp b/src/mesa/drivers/dri/i965/brw_fs_saturate_propagation.cpp index d65b2f14e13..4c4b6bf47a8 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_saturate_propagation.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_saturate_propagation.cpp @@ -48,13 +48,8 @@ opt_saturate_propagation_local(fs_visitor *v, bblock_t *block) int src_var = v->live_intervals->var_from_reg(&inst->src[0]); int src_end_ip = v->live_intervals->end[src_var]; - int scan_ip = ip; bool interfered = false; - for (fs_inst *scan_inst = (fs_inst *) inst->prev; - scan_inst != block->start->prev; - scan_inst = (fs_inst *) scan_inst->prev) { - scan_ip--; - + foreach_inst_in_block_reverse_starting_from(fs_inst, scan_inst, inst, block) { if (scan_inst->dst.file == GRF && scan_inst->dst.reg == inst->src[0].reg && scan_inst->dst.reg_offset == inst->src[0].reg_offset && diff --git a/src/mesa/drivers/dri/i965/brw_fs_sel_peephole.cpp b/src/mesa/drivers/dri/i965/brw_fs_sel_peephole.cpp index 2437a2f2ae1..28e41638e03 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_sel_peephole.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_sel_peephole.cpp @@ -41,9 +41,9 @@ * Scans forwards from an IF counting consecutive MOV instructions in the * "then" and "else" blocks of the if statement. * - * A pointer to the fs_inst* for IF is passed as the argument. The - * function stores pointers to the MOV instructions in the and - * arrays. + * A pointer to the bblock_t following the IF is passed as the + * argument. The function stores pointers to the MOV instructions in the + * and arrays. * * \return the minimum number of MOVs found in the two branches or zero if * an error occurred. @@ -62,26 +62,23 @@ */ static int count_movs_from_if(fs_inst *then_mov[MAX_MOVS], fs_inst *else_mov[MAX_MOVS], - fs_inst *if_inst, fs_inst *else_inst) + bblock_t *then_block, bblock_t *else_block) { - fs_inst *m = if_inst; - - assert(m->opcode == BRW_OPCODE_IF); - m = (fs_inst *) m->next; - int then_movs = 0; - while (then_movs < MAX_MOVS && m->opcode == BRW_OPCODE_MOV) { - then_mov[then_movs] = m; - m = (fs_inst *) m->next; + foreach_inst_in_block(fs_inst, inst, then_block) { + if (then_movs == MAX_MOVS || inst->opcode != BRW_OPCODE_MOV) + break; + + then_mov[then_movs] = inst; then_movs++; } - m = (fs_inst *) else_inst->next; - int else_movs = 0; - while (else_movs < MAX_MOVS && m->opcode == BRW_OPCODE_MOV) { - else_mov[else_movs] = m; - m = (fs_inst *) m->next; + foreach_inst_in_block(fs_inst, inst, else_block) { + if (else_movs == MAX_MOVS || inst->opcode != BRW_OPCODE_MOV) + break; + + else_mov[else_movs] = inst; else_movs++; } @@ -138,13 +135,15 @@ fs_visitor::opt_peephole_sel() if (!block->else_block) continue; - fs_inst *else_inst = (fs_inst *) block->else_block->end; - assert(else_inst->opcode == BRW_OPCODE_ELSE); + assert(block->else_block->end->opcode == BRW_OPCODE_ELSE); fs_inst *else_mov[MAX_MOVS] = { NULL }; fs_inst *then_mov[MAX_MOVS] = { NULL }; - int movs = count_movs_from_if(then_mov, else_mov, if_inst, else_inst); + bblock_t *then_block = (bblock_t *)block->link.next; + bblock_t *else_block = (bblock_t *)block->else_block->link.next; + + int movs = count_movs_from_if(then_mov, else_mov, then_block, else_block); if (movs == 0) continue; @@ -213,9 +212,6 @@ fs_visitor::opt_peephole_sel() if_inst->insert_before(block, cmp_inst); } - bblock_t *then_block = (bblock_t *)block->link.next; - bblock_t *else_block = (bblock_t *)block->else_block->link.next; - for (int i = 0; i < movs; i++) { if (mov_imm_inst[i]) if_inst->insert_before(block, mov_imm_inst[i]);