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 <topi.pohjolainen@intel.com>
This commit is contained in:
parent
7119712f45
commit
f0598d413b
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -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 <if_inst> argument. The
|
||||
* function stores pointers to the MOV instructions in the <then_mov> and
|
||||
* <else_mov> arrays.
|
||||
* A pointer to the bblock_t following the IF is passed as the <then_block>
|
||||
* argument. The function stores pointers to the MOV instructions in the
|
||||
* <then_mov> and <else_mov> 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]);
|
||||
|
|
Loading…
Reference in New Issue