[Mesa-dev] [PATCH 20/20] i965/fs: Preserve CFG in predicated break pass.
Pohjolainen, Topi
topi.pohjolainen at intel.com
Tue Aug 19 01:52:16 PDT 2014
On Thu, Jul 24, 2014 at 07:54:27PM -0700, Matt Turner wrote:
> 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.
> ---
> .../dri/i965/brw_fs_peephole_predicated_break.cpp | 29 +++++++++++++++++++---
> 1 file 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 445d10e..ab197ee 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);
I'm just checking how well I understood things. As we don't have a method
remove_successor() we need to call make_empty() and then add jump_block
again as a successor. It was already a successor before we called make_empty(),
right? (Above we have "if_block = (bblock_t *)jump_block->link.prev").
> + jump_block->add_successor(cfg->mem_ctx, endif_block);
And the same thing applies here, we called make_empty() to clear the parent
list of endif_block so we need to associate jump_block and endif_block again.
Given that this is how it works:
Reviewed-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
> +
> + 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;
> }
> --
> 1.8.5.5
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list