diff options
author | Matt Turner <[email protected]> | 2014-07-17 10:50:31 -0700 |
---|---|---|
committer | Matt Turner <[email protected]> | 2014-08-22 10:23:34 -0700 |
commit | b8aa1005c82ff732f714cd0dcca39775aa368dd7 (patch) | |
tree | a9cce4b68b7eba7cdbc5bf6f74309dc441561e9a /src/mesa/drivers | |
parent | 3c4c2a6e300fccbbec89f149e05ff086d6774319 (diff) |
i965/fs: Preserve CFG in predicated break pass.
Operating on this code,
B0: ...
cmp.ne.f0(8)
(+f0) if(8)
B1: break(8)
B2: endif(8)
We can delete B2 without attempting to merge any blocks, since the
break/continue instruction necessarily ends the previous block.
After deleting the if instruction, we attempt to merge blocks B0 and B1.
Reviewed-by: Topi Pohjolainen <[email protected]>
Diffstat (limited to 'src/mesa/drivers')
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs_peephole_predicated_break.cpp | 29 |
1 files changed, 25 insertions, 4 deletions
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 445d10e9b7d..ab197ee4694 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 @@ -64,27 +64,48 @@ fs_visitor::opt_peephole_predicated_break() if (endif_inst->opcode != BRW_OPCODE_ENDIF) continue; + bblock_t *jump_block = block; + bblock_t *if_block = (bblock_t *)jump_block->link.prev; + bblock_t *endif_block = (bblock_t *)jump_block->link.next; + /* For Sandybridge with IF with embedded comparison we need to emit an * instruction to set the flag register. */ if (brw->gen == 6 && if_inst->conditional_mod) { fs_inst *cmp_inst = CMP(reg_null_d, if_inst->src[0], if_inst->src[1], if_inst->conditional_mod); - if_inst->insert_before(cmp_inst); + if_inst->insert_before(if_block, cmp_inst); jump_inst->predicate = BRW_PREDICATE_NORMAL; } else { jump_inst->predicate = if_inst->predicate; jump_inst->predicate_inverse = if_inst->predicate_inverse; } - if_inst->remove(); - endif_inst->remove(); + bblock_t *earlier_block = if_block; + if (if_block->start_ip == if_block->end_ip) { + earlier_block = (bblock_t *)if_block->link.prev; + } + + if_inst->remove(if_block); + endif_inst->remove(endif_block); + + if_block->children.make_empty(); + endif_block->parents.make_empty(); + + if_block->add_successor(cfg->mem_ctx, jump_block); + jump_block->add_successor(cfg->mem_ctx, endif_block); + + if (earlier_block->can_combine_with(jump_block)) { + earlier_block->combine_with(jump_block); + + block = earlier_block; + } progress = true; } if (progress) - invalidate_live_intervals(); + invalidate_live_intervals(false); return progress; } |